1

I've been migrating an old javascript project to GAS and am hitting a blocker on trying to run namespace functions from the client-side web app. Quick code example:

var foo = function() {
  function doBar() {
    //do stuff
  }

  function doBang() {
    //do stuff
  }

  return {
  bar:doBar,
  bang:doBang
  }
}();

While this would be easy to call on the server side through foo.bar(), I have hit a wall in trying to speak to these functions from my web app. I was hoping to do something like this:

<script>
  google.script.run.withSuccessHandler(callback).foo.bar();
  function callback() {
    //do stuff
  }
</script>

But alas this does not seem to work. Is there something I am missing, or another way to get this working without having some form of handler function, not contained in a namespace, which passes through to my namespaces?

As this is a project migration, I have a very well structured but huge, set of namespaces; This would require a very long and robust hander function, so I would like to avoid doing so if possible.

5
  • Why not just pass as a parameter? google.script.run.withSuccessHandler(callback).foo(internalFunctionName) Commented Mar 31, 2022 at 13:10
  • @TheMaster unless I am misunderstanding you, that's what I meant by using a handler or router function. A nightmare to do in this case, because I have many hundreds of routes throughout my namespaces and I am not overly excited about using evals. Commented Mar 31, 2022 at 20:10
  • Not seeing the issue. Seems to me like a two line modification? return ({ bar:doBar, bang:doBang })[internalFunctionName]()? Commented Mar 31, 2022 at 21:09
  • @TheMaster I am not sure that I am following what you mean. Would you mind elaborating? Commented Mar 31, 2022 at 23:11
  • Would you mind elaborating how a handler function would be hard by editing your question? Commented Apr 1, 2022 at 6:46

2 Answers 2

-1

You would need that handler function. Apps Script doesn't understand you are calling a server-side function if you add the dot, and so you get this error:

TypeError: Cannot read properties of undefined (reading 'bar')

Feature request:

I'd suggest you to request this feature using this Issue Tracker template, if you'd like to see this implemented.

Sign up to request clarification or add additional context in comments.

Comments

-1

Class google.script.run is a client-side API to server side Google Apps Script scripts. A server side script such as in Code.gs bound to a Google Sheet like:

function foo(stuff)
{ let serverStuff = stuff; }

is called by a line of code such as some Javascript in a webpage like

<script>
  function doFooStuff()
  {
    let pageStuff = { this: 1, that: 2};
    google.script.run.foo(pageStuff);
  }
  doFooStuff();
  doOtherStuff();
</script>

Since the google.script.run.foo(stuff); call is async, it will continue execution in the page JS at the next line doOtherStuff(); while the foo(stuff) call is still executing on the server. That async call returns only void, not any return value from foo(stuff); because foo(stuff) hasn't completed executing yet and the next line executed in the page JS starts before foo(stuff) even returns the void.

This is why google.script.run provides withFailureHandler(function) and withSuccessHandler(function), whose function arguments are called back when foo(stuff) server function returns (when the server function throws an exception or not, respectively), which receive the foo(stuff) return value. So sync execution continues in the callback function in the JS in the page.

The namespaces of the server GAS and the page JS are entirely separate, as is the rest of their execution environments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.