I have a button (in HTML) that both calls for a function LoginInfoInput(...)
and redirect to a page (href="..."
), that is:
<a onclick="LoginInfoInput('<?!= userID; ?>')" href="<?= ScriptApp.getService().getUrl(); ?>?v=form&userID=<?!= userID; ?>" class="waves-effect waves-light btn-large">Log In</a>
,
where LoginInfoInput(...)
is a javascript function that will trigger my google apps script (GS) function. The triggered GS function will then insert data into my spreadsheet. Meanwhile, the redirected URL will pass though my doGet()
function. To determine the outcome, it gets data from my spreadsheet. My problem is that the spreadsheet is not always updated in time before redirecting the page takes action.
My attempt to solve the problem has been to wait/pause with a while-loop. However, when the while-loop is active during which the data becomes available in a spreadsheet (at least visually) does not work, i.e., the interesting data is not accessible. Note, I have also during the while-loop added the option to update the variable that stores the spreadsheet data (calling SpreadsheetApp.openByUrl(url)), however, without any improvement.
Update
My LoginInfoInput()
(in JavaScript) is as follows:
function LoginInfoInput(userID){
var userLO = document.getElementById("id_loginLO").value;
var userPassword = document.getElementById("id_password").value;
google.script.run.LoginAdd(userLO, userPassword, userID);
}
Solution
My solution was a combination of the answer provided by @IMTheNachoMan see below and my discovery that the added data in GS to Spreadsheet can be delayed if not forcing the data to be updated. To force an update, one call SpreadsheetApp.flush();
link after inserting the data in Spreadsheet, in the GS function. From my understanding, the data needs to be in my Spreadsheet before I change my (GS)-based page as it will try to access the Spreadsheet at the time my (GS)-based page is called rather than when I call for my Spreadsheet when the data is available (by waiting/using while-loop).
Replace your <a...
with this:
<a onclick="return LoginInfoInput(this, '<?!= userID; ?>');" href="<?= ScriptApp.getService().getUrl(); ?>?v=form&userID=<?!= userID; ?>" class="waves-effect waves-light btn-large">Log In</a>
Replace your function with this:
function LoginInfoInput(a, userID)
{
if(a.className == "done")
{
return true;
}
else
{
google.script.run.withSuccessHandler(function(){
a.className = "done";
a.click();
}).LoginAdd();
}
}
When the user clicks the link, className
is not done
so it calls your GAS function and returns false so the href
is not opened. When the GAS function is done, it sets the className
and then sets the clicks the link again. This time it returns true so the href
would get run.
Does that make sense?
Note, you can also use withUserObject
to pass the URL from a
around.
Reference: https://developers.google.com/apps-script/guides/html/reference/run