2

I have several spreadsheets from which i would like to be able to run the same code. So i created a .gs library. One of the things that the library does is create a modal in the active sheet using htmlService. The HTML code is also part of the library. On each bounded script, i add a menu item to the sheet that allows the user to call the library function. However, i am running into issues when trying to access the active sheet's data from the HTML using google.script.run. I have tried several things:

Test 1

First i tried having the HTML call a fn in the library gs, assuming it would be within scope. The code looked like this:

bounded.gs

function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('myMenu')
  .addItem('Run Custom Function', 'myLibrary.createMyModal')
}

myLibrary.gs

function createMyModal() {
  var widget = HtmlService.createHtmlOutputFromFile('modalHTMLfile');
  SpreadsheetApp.getUi().showModalDialog(widget, "title");
}


function helloWorld() {
  var ui = SpreadsheetApp.getUi(); 
  ui.alert('hello, world!');
}

modalHTMLfile.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onClickFn() {
        google.script.run.helloWorld();

      }
    </script>
  </head>
  <body>
    <button onclick='onClickFn();'>click me!</button>
  </body>
</html>

The modal generates just fine but when i click the button, it generates an error in the console: "Uncaught TypeError: google.script.run.helloWorld is not a function"

So i figured that there was an issue of scope, and i should put helloWorld in the bounded .gs:

Test 2

I moved the fn helloWorld into the bounded .gs as follows:

bounded.gs

function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('myMenu')
  .addItem('Run Custom Function', 'myLibrary.createMyModal')
}

function helloWorld() {
  var ui = SpreadsheetApp.getUi(); 
  ui.alert('hello, world!');
}

myLibrary.gs

function createMyModal() {
  var widget = HtmlService.createHtmlOutputFromFile('modalHTMLfile');
  SpreadsheetApp.getUi().showModalDialog(widget, "title");
}

modalHTMLfile.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onClickFn() {
        google.script.run.helloWorld();

      }
    </script>
  </head>
  <body>
    <button onclick='onClickFn();'>click me!</button>
  </body>
</html>

This time, when i clicked the button, something happened on the server side (see image below), but another error message appeared. This time, "Uncaught ScriptError: We're sorry, a server error occurred" See this image. Which led me to test #3:

Test 3

Soooo i did some questing around the interwebs and found some suggestions on stack exchange including to have two fns with the same name, an empty one in the bounded script and the real function in the library gs. So i tried that...here's the code:

bounded.gs

function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('myMenu')
  .addItem('Run Custom Function', 'myLibrary.createMyModal')
}

function helloWorld() {
  //placeholder function to "make things work"
}

myLibrary.gs

function createMyModal() {
  var widget = HtmlService.createHtmlOutputFromFile('modalHTMLfile');
  SpreadsheetApp.getUi().showModalDialog(widget, "title");
}

function helloWorld() {
  var ui = SpreadsheetApp.getUi(); 
  ui.alert('hello, world!');
}

modalHTMLfile.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onClickFn() {
        google.script.run.helloWorld();

      }
    </script>
  </head>
  <body>
    <button onclick='onClickFn();'>click me!</button>
  </body>
</html>

This third test yielded the same error as Test 2.

Test 4

For all three of the previous tests I included myLibrary in bounded.gs using Development Mode and i read something online suggesting that running in Development Mode can cause this issue. So i tried using the most up to date deployment of the library.

This is what my library deployment looks like (v5)

Library deployment

And when i click the button, i get an error message showing that the library is not recognized:

error message

--

I'm metaphorically pulling my hair out over here, does anyone have any suggestions? Is this even possible? I couuuuuuld put all the code in the bounded.gs file but i have 8 spreadsheets and i'd really love to avoid having 8 identical yet separate code bases to keep updated (that's the point of the library in the first place XD).

Thank you!!!

ask53
  • 21
  • 4
  • 1
    I believe the `helloWorld` method is out of scope in your first example as you pointed out, but when I copy the `helloWorld` method into the bounded script (as you did in your second test) everything works as expected I think (ie I don't get an error and I see an alert message). – Miguel Rivera Rios Jul 13 '23 at 20:35
  • Just to be safe it would be wise to wrap the google.script.run in to an onload. – Cooper Jul 13 '23 at 21:33
  • Thanks @Cooper, i did that in my original code but left it out in the example above for simplicity -- same behavior. – ask53 Jul 14 '23 at 13:48
  • At @MiguelRiveraRios thanks for testing this out and sharing your experience. I'll go back and try #Test 2 again and look for typos/bugs. One question: when you tried this out, is your library attached to the bounded script in Development Mode or did you use a deployed version? – ask53 Jul 14 '23 at 13:49
  • @ask53 Originally I was just attaching the library via dev mode, but I just tried it with a deployed version and it still seems to work just fine. I'm pretty sure I reproduced your example exactly as you explained it above and it seems to work. The server error you are seeing is kind of generic, so it's a little hard to debug. I'm sure you're dealing with a more complex situation than the example you provided, but I recall sometimes seeing that kind of error if I was not correctly serving an HTML response. – Miguel Rivera Rios Jul 14 '23 at 14:37
  • Regarding #2, The sheet needs to be open for the alert to show up. Also the error is probably just because there isn't a ``return`` in the `helloWorld`(not that it matters, as far as the server side is concerned). – TheMaster Jul 14 '23 at 14:41
  • Hi @TheMaster, thanks for your comment, i hadn't thought about a return statement. Unfortunately, i added one and no change. – ask53 Jul 14 '23 at 15:51
  • @MiguelRiveraRios thank you! Bizarre. You're right, my real code is more complicated than the above example but maybe i'll try starting with the example code myself and building up to the real code to see where the bug comes in. Much appreciated!!! – ask53 Jul 14 '23 at 15:52
  • 1
    @ask53 Once you get that sorted, I would also recommend checking out this answer (https://stackoverflow.com/a/48933031/13771937) to help keep you from having to copy and paste into multiple script files, which I believe was your initial concern. It's still a little hacky, but you might be able to add the `callLibraryFunction` to the bound scripts so you can still separate the real logic in the libraries. – Miguel Rivera Rios Jul 14 '23 at 15:58
  • hi again, all, thanks for your support. UPDATE: When working with the code from **TEST #2** above as @MiguelRiveraRios suggested, i was getting the same error as i previously described. I usually develop in Firefox. However, the same code works perfectly in Chrome! Indeed, when i ran my original code in Chrome, it worked perfectly! Any thoughts as to why this might be and a cross-browser solution? – ask53 Jul 14 '23 at 16:17
  • @MiguelRiveraRios haha thank you!!! That was one of the first things i tried (i actually still have the code copy-pasted from that thread in a comment on my script for when i get this cross-file thing sorted out XD) Its hacky but very useful! – ask53 Jul 14 '23 at 16:21
  • @ask53 Just tested it out on firefox myself and it works as expected for me. I'm not sure what the issue is, but just googling a little it seems some people were able to resolve this specific bug by re-deploying the library: https://stackoverflow.com/questions/71611207/web-application-using-a-library-shows-were-sorry-a-server-error-occurred-while – Miguel Rivera Rios Jul 14 '23 at 16:30
  • 1
    Please add success and failure handlers. And logging the errors inside the handler. – TheMaster Jul 14 '23 at 16:36
  • @MiguelRiveraRios thanks so much for trying all this stuff out! See my answer below, i think it had to do with the hierarchy of accounts (i was logged into several accounts and running the code from an account that was not the default). Seems like it isn't actually a browser issue but that switching browsers switched which accounts were logged into the browser session. Thanks again, yall people are so supportive!!! – ask53 Jul 14 '23 at 16:58
  • @TheMaster thnks for the suggestion. I had success and failure handlers and stripped them out to make the code above more readable. I just added them back in as per your suggestion and logged the error. However, the returned error is equally cryptic as before: "ScriptError: We're sorry, a server error occurred while reading from storage. Error code NOT_FOUND." – ask53 Jul 14 '23 at 17:04

1 Answers1

0

tl;dr: Make sure that you are signed into the Google Account you are using to run the code as the default account in the browser.


Ok, it seems like the issue is how i am logged into Google. (Thanks to prompting from comments on this thread: Google.script.run functions failing in firefox, safari)

I typically develop from my work account which is user #1 (u=1) in my Firefox session (my personal account is the default account, u=0). This configuration leads to the bugs described in the original post. However, when i am using an Incognito Window in Firefox, it works when i'm only signed into my work account. It also works fine when my work account (the owner of the relevant sheets and scripts) is the default account and the browser is also signed into my personal account. In Incognito mode, when i swap the accounts so that they match my non-Incognito configuration (personal=0, working=1) i run into the errors again.

Seems likely that this has something to do with the default account not having permission to access the scripts and is likely a Google-side bug.

Thanks to everyone who commented for your support on this!!!

ask53
  • 21
  • 4