google.script.run.myFunction() doesn't call server myFunction() from client HTML script

3.2k Views Asked by At

According to the documentation, calling a Google Apps Script function from a client HTML script should be as simple as google.script.run.myFunction(). However it doesn't seem to work for me:

My Code

function onOpen() {
  SpreadsheetApp.getUi()
      .createMenu('Dialog')
      .addItem('Open', 'openDialog')
      .addToUi();
}

function openDialog() {
  var html = HtmlService.createHtmlOutputFromFile('Index')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi()
      .showModalDialog(html, 'My Dialog');
}

function doSomething() {
  var sheet = SpreadsheetApp.getActive().getActiveSheet();
  sheet.getRange(sheet.getLastRow()+1, 1).setValue("Hello :)");
}

Note that calling doSomething() from the IDE runs smoothly. However not from the HTML script:

My HTML

<script>
google.script.run.doSomething();
</script>
2

There are 2 best solutions below

3
On BEST ANSWER

That appears to be all about timing - google.script.run may be getting called before the client-server connection is ready*. The usual intent of displaying a user interface is to interact with a user - and because people are much slower than machines, you'd not encounter this problem.

Even a short delay to display a toast is enough to make it work.

function doSomething() {
  SpreadsheetApp.getActive().toast("hello")
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.appendRow(["Hello :)"])
  return true;
}

Free bonus! Thinking ahead to the next problem you'll run into, note the return statement. A server function must have some kind of return to cause a callback to the google.script.run.onSuccess() handler.


*Edit - Something isn't quite right with this explanation, since the toast call is on the server. Would be nice if a Googler would speak up to offer a better explanation.

1
On

I use it normally, and it works fine.

But I never tried it before the page load. Since Google has a lot of security barriers, such as replacing the html body with its own custom body, I think it's worth trying to call it in a handler for the page load.

Try putting alerts in the handlers (see below) to see if it is really being run. Any little mistake in other parts of the html code often makes the entire script simply not run.

Things to be aware of: if you have global variables in your server side script, these will not persist!!! They will reset everytime you use google.script.run. So, make sure doSomething() has everything it needs on its own.

And if you expect to see a result after doSomething(), consider adding the handlers to google.script.run. You server side script will not be able to change the user interface nor open a new one if it's modal. (Never tried non modal...)

google.script.run
    .withSuccessHandler(function(data,element){window.alert("executed");})
    .withFailureHandler(function(msg,element){window.alert("failed"); })
    .doSomething();

If none of the messages appear, the problem is not here, but elsewhere. Some other thing is preventing your script from even starting.