问题
I created an array in a separate GS file using the code provided below. I tried calling it in my HTML file. My goal is to compare the contents the array to the parameter email
. However, the value returned by google.script.run.withSuccessHandler() is undefined
//in GS
function mailGetter()
{
//open sheet
var sheet = SpreadsheetApp.openByUrl("https://sheet.url").getSheetByName("Email Sheet").activate();
//get size of given row range
var row_data_email = sheet.getRange("C2:C").getValues();
var emailArray = row_data_email.join().split(',').filter(Boolean);
Logger.log(emailArray);
return emailArray;
}
//in HTML
function checkEmail(email)
{
var reg1 = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/;
var arraySize = google.script.run.withSuccessHandler(misc).sizeGetter();
console.log(arraySize);
var emailArray = new Array(arraySize);
emailArray = google.script.run.withSuccessHandler(misc).mailGetter();
console.log(emailArray);
if (reg1.test(email) == false)
{
emails.style.border = "1px solid red";
document.getElementById('submitBtn').disabled = true;
}
else if (reg1.test(email) == true)
{
emails.style.border = "1px solid green";
document.getElementById('submitBtn').disabled = false;
}
for (var row = 0; row < arraySize; row++)
{
if (emailArray[row][0] == email)
{
emails.style.border = "1px solid green";
document.getElementById('submitBtn').disabled = false;
break;
}
else if (emailArray[row][0] != email)
{
emails.style.border = "1px solid red";
document.getElementById('submitBtn').disabled = true;
}
}
}
function misc()
{
console.log("Pass");
}
回答1:
Issue:
- Using a asynchronous function's(
google.script.run
) return value, which will always beundefined
.
Solution:
- Use successHandler as mentioned in another answer or We can use promises with async/await.
Snippet:
/*Create a promise around old callback api*/
const p = func =>
new Promise(resolve=>
google.script.run.withSuccessHandler(resolve)[func]()
);
async function checkEmail(email) //modified
{
var arraySize = await p('sizeGetter');//Wait to resolve
console.log(arraySize);
//var emailArray = new Array(arraySize);
var emailArray = await p('mailGetter');//Wait to resolve
console.log(emailArray);
//....
}
Note:
- It's better to reduce the number of calls to the server. If you can combine both
Getter
s to a single server function, it'll be better. - The above is a snippet showing how to use
async
/await
. But if you wait for each response from the server as shown above, your front end/UI will be slow. Wait only if absolutely necessary. Calls to server should be non-blocking/asynchronous.
References:
- Promises
- async
- await
回答2:
Issue is in these lines:
emailArray = google.script.run.withSuccessHandler(misc).mailGetter();
console.log(emailArray);
You're trying to execute mailGetter()
and expecting it to return value which you're storing in emailArray
but this method is asynchronous and does not return directly
Rather you'll get the value in callback which you have defined as SuccessHandler
Suggested solutions :
- Calling Apps Script functions from a template : https://developers.google.com/apps-script/guides/html/templates#apps_script_code_in_scriptlets
- Calling Apps Script APIs directly : https://developers.google.com/apps-script/guides/html/templates#calling_apps_script_apis_directly
- Pushing variables to templates : https://developers.google.com/apps-script/guides/html/templates#pushing_variables_to_templates
Reference : https://developers.google.com/apps-script/guides/html/reference/run#myFunction(...)
来源:https://stackoverflow.com/questions/57195338/google-script-run-withsuccesshandler-returns-undefined