0

I am writing a webapp using Google Apps Script.

To reduce loading times I let doGet(e) load a small file with some javascript to asynchronously load other JS and CSS.

Loading external resources works fine of course:

<head>
  <!-- loading external resources works fine of course -->
  <script src="https://cdnjs.cloudflare.c[...]/jquery.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.clou[...].1/jquery-ui.min.css">
</head>

But from what I know this cannot be done with code inside my apps script project because I cannot provide a direct link to the file. That's why I add a little <script>:

function loadScript(filePath) {
  google.script.run.withSuccessHandler(function(returnedValueFromGAS) {
    $('body').append(returnedValueFromGAS);
  }).loadScript(filePath);

  loadScript('someScriptFilepath');
  loadScript('someStyleFilepath')
}

In this manner I add <script> and <style> tags to my HTML. And I would like to have not one callback for every loaded file, but one callback when all my (script-)files are loaded.

This works fine so far with one major drawback: The Window-Load-Event is not of any use anymore.

How can I load JS and CSS files in the <head> like I would do in other environments so that the load-event still is of use for me?

3
  • of any use anymore. Why not? Commented Aug 13, 2019 at 7:01
  • Because the event fires after my tiny document has loaded but not any of my JS or CSS which is loaded by my JS. Commented Aug 13, 2019 at 7:06
  • Could you give a specific example of what you're trying to do? Why not include it in head? If not, how are you loading? If you're loading in script tags, load event will still fire from that object, which you can listen to. If you're loading through google.script.run,successHandler will act as a callback Commented Aug 13, 2019 at 7:17

1 Answer 1

2

And I would like to have not one callback for every loaded file, but one callback when all my (script-)files are loaded.

Issue/Solution:

  • The script is calling server functions one by one, instead of one after another(or one inside another). You should nest callbacks('Callback hell') or use promises/async/await.

Snippet:

/**
 * Create a promise around old callback api
 * @param {String} func The server function to call
 * @param {Object} args The arguments to the server function 
 * @return Promise 
 */
const GSR = (func,...args) => 
  new Promise((resolve,reject)=>
    google.script.run
        .withSuccessHandler(resolve)
        .withFailureHandler(reject)[func](...args)
  );

const bodyAppend = function(returnedValueFromGAS) {
    $('body').append(returnedValueFromGAS);
}

//call GSR and append 
const GSRa = (func, ...args) => 
    GSR(func, ...args)
      .then(bodyAppend)
      .catch(e=>console.error(e.message));

function loadScriptClient() {//modified
  //Can also use async/await here
  Promise.all([GSRa('loadScript','someScriptFilepath'), GSRa('loadScript','someStyleFilepath')])
    .then(/*All Files loaded and appended at this point; Provide a final callback function here*/)
    .catch(e=>console.error(e.message));
}

References:

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

Comments

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.