1

Maybe i'm misunderstanding how event objects work, but i've been following a tutorial on how to get google forms to send a pdf every time the form is submitted. This led me to the function onFormSubmit(e){ } and then pull e.namedValues, but it keeps giving me

TypeError: Cannot read properties of undefined (reading 'namedValues') onFormSubmit @ Code.gs:2

What am I not understanding that's leading me to do this wrong? I've got the trigger set up that when the form is submmited to run onFormSubit, but i just can't get it to use event objects.

function onFormSubmit(e) {
  const info = e.namedValues;
  createPDF(info);
}

function createPDF(info ){

const pdfFolder = DriveApp.getFolderById("1g58GUQLPjPonsHtxj5LlxyoDgXs5wj2R");
const tempFolder = DriveApp.getFolderById("1Fkzf0xeZcedfq7BF2k3V4mn4Pz_LsXsv");
const templateDoc = DriveApp.getFileById("1eOqom8SqhuDUpIqYEVum-EvQ09cVz2d_XCLcRNAz8jE");

const newTempFile = templateDoc.makeCopy(tempFolder);

const openDoc = DocumentApp.openById(newTempFile.getId());
const body = openDoc.getBody();
body.replaceText("{fn}", info['First Name'][0]);
body.replaceText("{ln}", info['Last Name'][0]); 
body.replaceText("{bd}", info['Birthday'][0]);
body.replaceText("{em}", info['Email'][0]);
body.replaceText("{pn}", info['Phone Number'][0]);
body.replaceText("{pv}", info['Province'][0]);
body.replaceText("{cm}", info['Contact Method'][0]);
body.replaceText("{lg}", info['Language'][0]);
body.replaceText("{ts}", info['Type Of Service'][0]); //error TypeError: Cannot read properties of undefined (reading '0')
body.replaceText("{cn}", info['Child Name'][0]);
body.replaceText("{cbd}", info['Child Birthday'][0]);
body.replaceText("{sr}", info['Services Required'][0]);
body.replaceText("{stf}", info['Staff Requested'][0]);
body.replaceText("{pri}", info['Priority'][0]);
body.replaceText("{ref}", info['Referral'][0]);
body.replaceText("{jc}", info['Jane Consent'][0]);

openDoc.saveAndClose();

const blobPDF = newTempFile.getAs(MimeType.PDF);
const pdfFile = pdfFolder.createFile(blobPDF).setName(info['First Name'][0] + ' ' + (info['Last Name'][0] ));
tempFolder.removeFile(newTempFile);

}
3
  • 2
    You may be using the wrong onFormSubmit trigger. There are two one for the spreadsheet and one for the form. automation triggers
    – Cooper
    Commented Jan 29 at 15:55
  • Where did you create the script? As @Cooper says, is it on the spreadsheet or in the forms?
    – Lime Husky
    Commented Jan 29 at 16:50
  • @LimeHusky this is on the spreadsheet, i'm attempting to follow the guide at youtube.com/watch?v=EpZGvKIHmR8 Commented Jan 29 at 17:38

2 Answers 2

2

The error indicates that e is undefined, which means that you probably ran the function in the script editor. Don't run the code through the ▷ Run button in the script editor. If you do, the event parameter e won't be populated, causing the error you mention.

Instead, let the trigger run the function when you submit a new form response.

When the script project is bound to a spreadsheet, and the function runs when the "on form submit" trigger fires, e.namedValues will be present.

For debugging, see How can I test a trigger function in GAS?

1
1

@doubleunary said it correctly. In addition, I suggest using this code to combine all functions into one. In the last part, I changed tempFolder.removeFile(newTempFile); to newTempFile.setTrashed(true); because the removeFile method is deprecated. I changed it to setTrashed, which is the modern equivalent.

Code:

function onFormSubmit(e) {
  const info = e.namedValues;

  const pdfFolder = DriveApp.getFolderById("1g58GUQLPjPonsHtxj5LlxyoDgXs5wj2R");
  const tempFolder = DriveApp.getFolderById("1Fkzf0xeZcedfq7BF2k3V4mn4Pz_LsXsv");
  const templateDoc = DriveApp.getFileById("1eOqom8SqhuDUpIqYEVum-EvQ09cVz2d_XCLcRNAz8jE");

  const newTempFile = templateDoc.makeCopy(tempFolder);

  const openDoc = DocumentApp.openById(newTempFile.getId());
  const body = openDoc.getBody();
  body.replaceText("{fn}", info['First Name'][0]);
  body.replaceText("{ln}", info['Last Name'][0]);
  body.replaceText("{bd}", info['Birthday'][0]);
  body.replaceText("{em}", info['Email'][0]);
  body.replaceText("{pn}", info['Phone Number'][0]);
  body.replaceText("{pv}", info['Province'][0]);
  body.replaceText("{cm}", info['Contact Method'][0]);
  body.replaceText("{lg}", info['Language'][0]);
  body.replaceText("{ts}", info['Type Of Service'][0]);
  body.replaceText("{cn}", info['Child Name'][0]);
  body.replaceText("{cbd}", info['Child Birthday'][0]);
  body.replaceText("{sr}", info['Services Required'][0]);
  body.replaceText("{stf}", info['Staff Requested'][0]);
  body.replaceText("{pri}", info['Priority'][0]);
  body.replaceText("{ref}", info['Referral'][0]);
  body.replaceText("{jc}", info['Jane Consent'][0]);

  openDoc.saveAndClose();

  const blobPDF = newTempFile.getAs(MimeType.PDF);
  pdfFolder.createFile(blobPDF).setName(info['First Name'][0] + ' ' + (info['Last Name'][0]));
  // tempFolder.removeFile(newTempFile);
  newTempFile.setTrashed(true);
}

Reference: setTrashed(trashed)

4
  • 1
    "to improve the code" — see Functions should do one thing for additional ideas. Commented Jan 29 at 20:32
  • 1
    .getFilesByName(newTempFile) — that won't work, because newTempFile is a File rather than a string. Use newTempFile.setTrashed(true). Commented Jan 29 at 20:34
  • 1
    @doubleunary thanks for the feedback. I checked my previous code again and it was actually deleting the file. However, I edited the code based on your suggestion because it's better.
    – leylou
    Commented Jan 29 at 20:52
  • 1
    @doubleunary A valuable link. Speaking from personal experience, I do agree with the measurement of "Code Quality" (particularly my own code!)
    – Tedinoz
    Commented Feb 11 at 0:27

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.