One of the challenges when using htmlService is passing data from the server to client. Let’s look at an example.
Consider this –

the script

function doGet(e) {
   return HtmlService
      .createTemplateFromFile('mytemplate')
      .evaluate();
}

function getValue() {
  return 'hello world';
}

the template

I get a correct hello world alert.

So now let’s try amending the script like this

var global = "hello world";
function doGet(e) {
   return HtmlService
      .createTemplateFromFile('mytemplate')
      .evaluate();
}

function getValue() {
  return global;
  }

It still works.

How about this.

var global;
function doGet(e) {
   global = "hello world";
   return HtmlService
      .createTemplateFromFile('mytemplate')
      .evaluate();
}

function getValue() {
  return global;
  }

This time I get undefined instead of ‘hello world’.

What’s going on ?

When you execute google.script.run() on the server, it initiatializes the script again. This means that any global variables are reinitialized each time. In other words – a global variable only retains its value inside the instantiation of its script. In the first case the same value would have been set as before – since it’s outside any function and would have been re-executed. In the second case, doGet() would have needed to be executed to give the variable a value. Since it is not, the variable remains as undefined.

This makes it fairly tricky to do things like pass parameters received by doGet(e) to a script running on the client-side. Approaches to this might be to use the propertyService, or perhaps the cacheService for when the call from google.script.run comes.

In some cases though, it’s not necessary. Here’s the approach I use (which avoids the call back to the server from the client script altogether).

My script

function doGet(e) {
   var data  = {text:"hello world"};
   
   // get the template
   var html = HtmlService
      .createTemplateFromFile('mytemplate')
      .evaluate()
      .getContent();
   
   // now pass the data via a script
   return HtmlService
     .createTemplate(html +    
       "")
        .evaluate();
}

My template

Using this method, we don’t need any global variables that would need reinitializing, because we evaluate a template that already contains the embedded variable data from the main script.

Explanation
Here’s the data we need to get to the client-side script.

var data  = {text:"hello world"};

The client script wants to do something with it – so we wrap the scripted actions in a function that expects its data as an argument.

Evaluate that template as normal, but get its content

// get the template
   var html = HtmlService
      .createTemplateFromFile('mytemplate')
      .evaluate()
	  .getContent();

Append the data right in your evaluated template, and include a call to the script that does the work. The data will actually be written as part of the script, then evaluate the whole thing.

// now pass the data via a script
   return HtmlService
     .createTemplate(html +    
       "")
		.evaluate();

Here’s what the overall evaluated script that HtmlService will finally execute, and why it works.



See Getting an htmlservice template from a library for more on this topic. This technique is illustrated in Displaying analytics data on site pages. You can also find out about How to pass non stringifyable objects to html service here.
For more like this see Google Apps Scripts Snippets
For help and more information join our forum, follow the blog, follow me on twitter