5

This problem has me wanting to pull my hair out. I am trying to pass a URL parameter to Google Apps Script containing the row ID (from a spreadsheet) for the data I'm wanting to present. My parameter is story. However, I'm getting all sorts of errors no matter what I try. The latest being:

TypeError: Cannot read property "parameter" from undefined. (line 2, file "Code", project "singleStory")

Below are my Code.gs and Index.html files (The project is not complete. This is just where I'm at so far.)

Code.gs

function doGet(e) {
    var i = e.parameter.story;
    return HtmlService
      .createTemplateFromFile('Index')
      .evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);

 function getData() {
 return SpreadsheetApp
      .openById("1Z582cnr03fkLC7xCca4pcj7QwDtSCS4KGneyFKMgdyo")
      .getSheetByName("StoryTopics")
      .getDataRange()
      .getValues();
 }
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <? var data = doGet(); ?>

<div id="container">
<div id="header">
<div id="topicname">
    <?= data[i][0] ?>
</div>
<div id="todaysdate">
<p>As of: <?= new Date() ?></p>
</div>
<div id="topictype">
<?= data[i][1] ?>
</div>
<div id="locale">
<?= data[i][2] ?>
</div>
</div>
<div id="contact_container">
<div id="subheader">
</div>
<div id="contact_name">
<?= data[i][3] ?>
</div>
<div id="contact_title">
<?= data[i][4] ?>, <?= data[i][5] ?>
</div>
<div id="contact_email">
<?= data[i][6] ?>
</div>
<div id="contact_phone">
<?= data[i][7] ?>
</div>
</div>
<div id="action_container">
<div id="subheader">
</div>
<table id="action_table">
<tr>
<td>
Date:
</td>
<td>
Type:
</td>
<td>
Description:
</td>
</tr>
</table>
</div>
<div id="story_container">
<div id="story_title">
</div>
<div id="story_content">
</div>
</div>
</div>
</body>
</html>

The URL + parameter I'm using to test is:

https://script.google.com/a/macros/--DOMAIN--/s/--SCRIPTID--/exec?story=3

Can anyone give me some ideas on why it's not working?

4
  • 1
    Please state exactly what you're trying to accomplish. It is not at all clear from your question. Commented Mar 2, 2016 at 5:21
  • What is the parameter e being passed into doGet()? I am not familiar with this way of calling AppScript functions, but it looks like the parameter is missing in your index.html Commented Mar 2, 2016 at 5:22
  • 1
    @nickpharris - that should be an event parameter, as described here. However, there is no event parameter being supplied to my copy of this code - something is Very Wrong. Commented Mar 2, 2016 at 20:38
  • 1
    Never mind - the problem is that you've got your templated HTML written incorrectly, so the web app cannot start properly. (It should NEVER call doGet() - the HTML is being generated by that function, so you're setting up an execution loop. The second invocation has no event parameter, so BOOM.) Commented Mar 2, 2016 at 20:59

1 Answer 1

6

TypeError: Cannot read property "parameter" from undefined. (line 2, file "Code", project "singleStory")

This tells you that the object you expect to contain the named property "parameter" is undefined.

Looking at your code (e.parameter.story), that's referring to the event parameter e. For those unfamiliar with this, when it's invoked in a deployed Web App, the specially-named doGet() function receives an event parameter, which is named e in this example.)

Why is e undefined here?

One reason that you might see this is if you're running the function from the debugger, not testing it as a web app. That's not your case, Kevin, since you are entering a URL into the browser to try to launch the web app.

The problem turns out to be in the Templated HTML. The very first statement in your HTML is:

<? var data = doGet(); ?>

This causes trouble as soon as we attempt to .evaluate() the template, as it re-invokes the doGet() function, this time without any event object. And it's that time around that spits out the error message.

You likely meant to do this, instead, to get the data from your spreadsheet:

<? var data = getData(); ?>

With that change in place, you now receive the event parameter e (which you always did...) and the code carries on. Until the next bug:

ReferenceError: "i" is not defined. (line 3, file "Code")

Now things get tricky, because the error is being reported against this statement in Code.gs:

return HtmlService
    .createTemplateFromFile('Index')
    .evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);

But wait! Wasn't i just defined in line 2? Yes, it was... However this error is about evaluate() trying to fill out the template, and your code doesn't yet set i for that. You'll need to break up this statement to first get the template, then set parameters for it, and finally evaluate it. Like this:

function doGet(e) {
  var i = e.parameter.story;

  // First, get the template
  var template = HtmlService.createTemplateFromFile('Index');

  // Second, set template parameters
  template.i = i;

  // Finally, evaluate() the template
  return template.evaluate()
                 .setSandboxMode(HtmlService.SandboxMode.IFRAME);

}  // <-- You had this on the other side of 'getData()'

That should get you rolling. You've got other errors:

  • The blocking of your functions is wrong, you want getData() at global scope, not within doGet().
  • You'll probably have to debug your template, follow the guidance in Debugging templates.
  • Templated code is enclosed <? thusly ?>, not <?= like this ?>.
Sign up to request clarification or add additional context in comments.

1 Comment

That fixed it indeed! Thank you SO very much! I certainly appreciate the step by step approach and detailed explanation of where the error was and how to fix it. I am a Google Apps Script novice, so I'm learning as I go. Thank you once again!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.