Home > Blockchain >  How to pass String data from PropertiesService on Google Apps Script to client code?
How to pass String data from PropertiesService on Google Apps Script to client code?

Time:10-17

How is the counter property read, incremented, and then written back to PropertiesServices?

Currently, that property is being logged as NaN.

server log:

increment
    incrementCounter
    Web App
    Oct 16, 2022, 4:20:11 PM
    0.224 s
    
Completed
Cloud logs
Oct 16, 2022, 4:20:11 PM
Info
NaN

client log:

addNote..
userCodeAppPanel:12 undefined
userCodeAppPanel:13 jkljkljkl;jkl;jklj
2849282381-warden_bin_i18n_warden.js:105 Net state changed from IDLE to BUSY
2849282381-warden_bin_i18n_warden.js:105 Net state changed from BUSY to IDLE
userCodeAppPanel:9 Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at userCodeAppPanel:9:62
    at Lf (445342555-mae_html_user_bin_i18n_mae_html_user.js:92:266)
    at 445342555-mae_html_user_bin_i18n_mae_html_user.js:25:132
    at Ug.V (445342555-mae_html_user_bin_i18n_mae_html_user.js:125:380)
    at Id (445342555-mae_html_user_bin_i18n_mae_html_user.js:56:477)
    at a (445342555-mae_html_user_bin_i18n_mae_html_user.js:54:52)
(anonymous) @ userCodeAppPanel:9
Lf @ 445342555-mae_html_user_bin_i18n_mae_html_user.js:92
(anonymous) @ 445342555-mae_html_user_bin_i18n_mae_html_user.js:25
Ug.V @ 445342555-mae_html_user_bin_i18n_mae_html_user.js:125
Id @ 445342555-mae_html_user_bin_i18n_mae_html_user.js:56
a @ 445342555-mae_html_user_bin_i18n_mae_html_user.js:54

html:

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <script>
    var counter = "65456456456456456456";
    var note = "";
    function addNote()
    {
      console.log("addNote..");
      note = document.getElementById("note").value;
      counter = google.script.run.withSuccessHandler((success) => {
        document.getElementById("successfulClick").innerHTML = success;
      })
      .incrementCounter();
      console.log(counter);
      console.log(note);
      document.getElementById("counter").textContent = counter;
      document.getElementById("note").textContent = note;
    }
  </script>
</head>

<body>
  <div id="success"></div> <br>
  <div id="counter"></div> <br>
  <div id="row"></div> <br>
  <br> <br> <br> <br> <br> <br>
  <input type="textarea" cols="40" rows="5" id="note" value=""/>
  <input type="button" value="addNote" onclick="addNote()" />
</body>

</html>

code:

function init() {
  PropertiesService.getScriptProperties().deleteAllProperties();
  PropertiesService.getScriptProperties().setProperty("counter","3");
}

function incrementCounter() {
  var counter = PropertiesService.getScriptProperties().getProperty(counter);
  counter = parseInt(counter);
  counter  ;
  PropertiesService.getScriptProperties().setProperty("counter",counter);
  Logger.log(counter);
  return counter;
}


function getUrl() {
  Logger.log("getUrl..");

  var url = ScriptApp.getService().getUrl();
  return url;
}



function doGet(e) {
  // Logger.log("doGet..");
  init();
  var htmlOutput = HtmlService.createTemplateFromFile('WebApp');
  htmlOutput.url = getUrl();
  return htmlOutput.evaluate();
}

From the client logs it looks like the counter in the HTML is null, and yet it was initialized with a value, if that's a correct reading of that log.

From the server logs, quite clearly the server side variable isn't a number, as it's logging NaN -- however, it should still have a value even if not a number. That property was initialized with a value.

CodePudding user response:

Modification points:

  • In your Google Apps Script side, counte of var counter = PropertiesService.getScriptProperties().getProperty(counter); is not declaread.
    • I thought that this might be the reason for your current issue of From the server logs, quite clearly the server side variable isn't a number, as it's logging NaN -- however, it should still have a value even if not a number..
  • In your Javascript side, google.script.run returns void. By this, counter is changed by counter = google.script.run.withSuccessHandler((success) => { document.getElementById("successfulClick").innerHTML = success; }). By this, undefined is shown in the log of console.log(counter);.
    • I thought that this might be the reason for your current issue of From the client logs it looks like the counter in the HTML is null, and yet it was initialized with a value, if that's a correct reading of that log..

When these points are reflected in your script, how about the following modification?

Modified script:

Google Apps Script side:

Please modify incrementCounter() as follows.

function incrementCounter() {
  var counter = PropertiesService.getScriptProperties().getProperty("counter"); // Modified
  counter = parseInt(counter, 10);
  counter  ;
  PropertiesService.getScriptProperties().setProperty("counter",counter);
  Logger.log(counter);
  return counter;
}

HTML side:

Please modify addNote() as follows.

function addNote() {
  console.log("addNote..");
  note = document.getElementById("note").value;
  google.script.run.withSuccessHandler((success) => { // Modified
    document.getElementById("successfulClick").innerHTML = success;
  })
  .incrementCounter();
  console.log(counter);
  console.log(note);
  document.getElementById("counter").textContent = counter;
  document.getElementById("note").textContent = note;
}
  • When these modifications are reflected in your script, the tag of successfulClick shows the returned value from incrementCounter(). And, the tag of counter shows var counter = "65456456456456456456";.

Reference:

CodePudding user response:

what was specifically missing was handling the return value from, in the below example, getFoo:

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <script>
    var foo = "foo";
    function loadFoo(){
      foo = "bar";

    console.log(foo);

    foo = google.script.run.withSuccessHandler((data) => {
        document.getElementById("foo").textContent = data;
      })
      .getFoo();

      console.log(foo);
      document.getElementById("foo").textContent = foo;
    }
  </script>
</head>

<body>
  <div id="foo">index</div>
  <br> <br> <br> <br> <br> <br>
  <input type="button" value="loadFoo" onclick="loadFoo()" />
</body>
</html>

code:

function getFoo() {
  var foo = "baz"
  Logger.log(foo);
  return foo;
}

function getUrl() {
  Logger.log("getUrl..");
  var url = ScriptApp.getService().getUrl();
  return url;
}


function doGet(e) {
  var htmlOutput = HtmlService.createTemplateFromFile('WebApp');
  htmlOutput.foo = "foo"   getFoo();
  htmlOutput.url = getUrl();
  return htmlOutput.evaluate();
}

Explanatory notes on the mechanics of why data is required above, and how exactly that works, appreciated.

  • Related