redditor
redditor

Reputation: 4266

Updating Google web app front end part way through script

I have a web app that on button click initiates a script and populates the return value in a span, similar to below:

page.html

<button id="btn">Run function</button>
<span id="result_span">
    <!--return value from doStuff goes here-->
</span>

<script>
    document.getElementById("btn").addEventListener("click",init_function);

    function init_function(){
      console.log('init')
      let updateLocation = document.querySelector('#result_span')

      function onFailure(error){
        let warning = `<span style="color:red">${error}</span>`;
          updateLocation.innerHTML = warning;
      };

      function onSuccess(element){
        let result = element;
        updateLocation.innerHTML = result;
      };

      google.script.run.withFailureHandler(onFailure)
        .withSuccessHandler(onSuccess)
        .doStuff();
    }
</script>

code.gs

function doStuff(){
    //do stuff
    return string;
}

This is working correctly, but how can I update the front end UI as the script runs. For example, something like:

function doStuff(){
    //do stuff
    update-the-user-part-one
    //do more stuff
    update-the-user-part-two
    //do even more stuff
    return string;
}

Unfortunately console.log('update-the-user-part-one') doesn't go the front end, but perhaps there is some way using callbacks or promise to have <span id="updates"></span> innerHTML update during the script.

Upvotes: 2

Views: 352

Answers (1)

NightEye
NightEye

Reputation: 11184

If what you want is realtime update on the site during the script's execution, I wasn't able to find any references or resources to make it work.

Although, I was able to somewhat simulate what you want below. This approach might not be optimal, but this will still achieve what you want (in appearance).

Assuming this is your function:

function doStuff(){
  // do part 1 then update site
  updateTheUserP1
  // do part 2 then update site
  updateTheUserP2
  // do the last part and return the final value
  string = "done all";

  return string;
}

I propose you separate your function into multiple functions depending on when you want the site updated. So I decided to divide it into 3 parts

function updateTheUserP1(){
  string = "done 1";
  // assuming part 1 finishes after 1 second
  Utilities.sleep(1000)
  return string;
}

function updateTheUserP2(){
  string = "done 2";
  // assuming part 2 finishes after 1 second
  Utilities.sleep(1000)
  return string;
}

function doStuff(){
  string = "done all";
  // assuming the last part finishes after 1 second
  Utilities.sleep(1000)
  return string;
}

Then you'll want your calls in the client side to cascade:

function do1(element){
  updateLocation.innerHTML = element;
  google.script.run.withFailureHandler(onFailure)
    .withSuccessHandler(do2)
    .updateTheUserP2();
};

function do2(element){
  updateLocation.innerHTML = element;
  google.script.run.withFailureHandler(onFailure)
    .withSuccessHandler(onSuccess)
    .doStuff();
};

function onSuccess(element){
  let result = element;
  updateLocation.innerHTML = result;
};

google.script.run.withFailureHandler(onFailure)
  .withSuccessHandler(do1)
  .updateTheUserP1(); 

Output:

output

Upvotes: 1

Related Questions