简体   繁体   中英

Server-side variables set by client call to server function persist? (No!)

I tried to use the Revealing module pattern in apps javascript. I like the idea, but what it seems to have most acutely revealed is my ignorance of 1) javascript 2) apps scripts and 3) how they interact.

That pattern works fine when running a function in the editor (see test() below), but when run from a live webapp, it breaks down. I have the impression that values in the server-side javascript cannot be set using closures.

Whenever I run getEmail or setEmail in the editor, things work fine. If I call them from a webapp, the values set by setEmail do not remain set, so another call to the getEmail will retrieve the original values and not the values that were set by setEmail.

If the same javascript code were in the html page as a script, the settings would stick, I believe. (ok... will have to test that...).

The working code: https://script.google.com/macros/s/AKfycbwrmi-b7J5Gqb_SDUUuiO-TTG31hQJVWtMLFvAPTPOb97qZaQw/exec

The code itself: https://script.google.com/d/1LNw54M-hMgafMfsnYBR0QzFlzXDhd9mFX4asghtqejJRC2Uh66zoFuAb/edit?usp=sharing

Core parts:

function doGet() {
  settings.setEmail("start email");
  return HtmlService.createTemplateFromFile('dialog')
            .evaluate()
            .setSandboxMode(HtmlService.SandboxMode.NATIVE)
}

var settings = (function () {
        var email = "blank";
        var getEmail= function () { return email}
        var setEmail= function (m) { email=m}

        return {
          getEmail: getEmail,
          setEmail: setEmail
        }
} ());

function getVal() { return settings.getEmail() }
function setVal(x) { settings.setEmail(x); return "set '" + x + "'"}

function test() {
  Logger.log(setVal("my email"));
  Logger.log(getVal());
}

Html code:

    <div id="output" >  <?= settings.getEmail()?> </div>
    <br>
    <input  id="input" size="20" type="string" />
    <input type="button" value="Set Value"  onclick="google.script.run.withSuccessHandler(serverSaid).setVal(document.getElementById('input').value);" />
    <input type="button" value="Get Value"  onclick="google.script.run.withSuccessHandler(serverSaid).getVal();" />

    <script>
    function serverSaid(reply) {
          var div = document.getElementById('output');
          var messages= div.innerHTML;
          div.innerHTML = messages +" | " + reply;
    }
    </script>

So, I tried doing the same thing client-side. It works as expected. Here is the HTML code:

<div id="output" >  </div>
<br>
<input  id="input" size="20" type="string" />
<input type="button" value="Set Value"  onclick="serverSaid(setVal(document.getElementById('input').value));" />
<input type="button" value="Get Value"  onclick="serverSaid(getVal());" />

<script>
function serverSaid(reply) {
      var div = document.getElementById('output');
      var messages= div.innerHTML;
      div.innerHTML = messages +" | " + reply;
}

/// everything below has been moved over from server-side 
var settings = (function () {
        var email = "blank";
        var getEmail= function () { return email}
        var setEmail= function (m) { email=m}

        return {
          getEmail: getEmail,
          setEmail: setEmail
        }
} ());

function getVal() { return settings.getEmail() }
function setVal(x) { settings.setEmail(x); return "set '" + x + "'"}

</script>

I think you misunderstood some things. If I understand well your problem, you are trying to call some server side functions to set/get a value. But you actually don't store this value server side ! Differences you get is because of different contexts.

When you use the editor, the script is executed in this own context, meaning all instantiated objects/variables will stay as long as the script is executed (as long as you stay on the page).

But when you call these functions from client side, the server script will be executed once after a call and then its context will be destroyed as you "leave" (end of the execution of the function) the server.

So the value is actually changed, but the context where the value is changed is destroyed after the end of the execution. Finally, when you call the get function, you recreate a brand new context where the value is instantiated with its default value.

To handle this, you have to store the variable somewhere, into a database, for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM