Get Multiple Corresponding Values From Different HTML Tags To Use In A Function
Solution 1:
Probably some of the issues with your client-side code are hidden in the details of the communication interface. As mentioned in comments, there are certain datatypes that cannot be passed between the Google Apps Script backend, and the HtmlService
client-side frontend. Particularly notable are the Date
restrictions.
As a general rule, unless I am passing single values, I will usually serialize a server-side value to JSON before sending it to the client. This makes certain that only serializable things are being transmitted (so no raw Date
objects are attempted, nor native Apps Script class objects).
Additionally, I have found that this makes returning large responses more stable: perhaps a return <large 2D array>
will occasionally be seen as undefined
in the client side, while return JSON.stringify(<same 2D array>)
will arrive safely as a JSON.parse
able parameter.
With that in mind, your use of synchronous code needs to be amended. The parameter given to withSuccessHandler
should be either a function variable or an inline function definition, e.g.
...
.withSuccessHandler(foo)
...
where elsewhere in the namespace one sees
function foo(retVal, uObj) { ... }
or
const foo = (retVal, uObj) => { ... }; // or const foo = function (retVal, uObj) { ... };
Inline syntax would be similar to:
...
.withSuccessHandler((retVal, uObj) => { ... })
// or
.withSuccessHandler(function (retVal, uObj) { ... })
...
In all these cases, the success handler is invoked with 2 arguments - the return value of the server-side function (arg1
), and the specified "user object" assigned to the invoked google.script.run
task runner (arg2
).
function getCheckedNames() {
//getting all checkboxes
const allCheckboxes = Array.from(document.getElementsByClassName("filled-in"));
//getting all <a> tag elements as a native Array.
const names = Array.from(document.getElementsByTagName("a"));
//Reduce from all names to only those that are "checked."
return allCheckboxes.reduce((arr, cb, i) => {
// Store the corresponding employee name for any checked checkbox
if (cb.value === true)
arr.push(names[i].value);
return arr;
}, []);
}
function requestCheckedCalendars() {
const chosenNames = getCheckedNames();
// Submit these names to the backend, to receive their calendar events.
// Async call, so we will include this object in our call so that the
// success handler callback can keep working with it.
google.script.run
.withUserObject(chosenNames)
.withSuccessHandler(requestCalendarEvents)
.loopToGetCals(JSON.stringify({names: chosenNames}));
}
/**
* @param {string[]} calendars An array of Google Calendar IDs
* @param {string[]} [chosenNames] An array of names associated with `calendars` (the "user object")
*/
function requestCalendarEvents(calendars, chosenNames) {
// Convert from JSON-serialized data to native Object types.
if (typeof calendars === "string")
calendars = JSON.parse(calendars);
if (typeof chosenNames === "string")
chosenNames = JSON.parse(chosenNames);
if (!chosenNames)
chosenNames = getCheckedNames();
const employees = {
names: chosenNames,
cals: calendars
};
//read inputs of start and end dates
const startdate = document.getElementById("startDate").value
const enddate = document.getElementById("endDate").value
//getting dates as UTC milliseconds
const startDate = new Date(startdate).getTime();
const endDate = new Date(enddate).getTime();
//call backend function to get calendar events
google.script.run
// .withSuccessHandler( <some client function> )
.getCalendarEvents(JSON.stringify(employees), startDate, endDate);
}
Other refs
(It's theoretically possible you could use Function#bind
to pre-pass some additional arguments to the function used as a success handler, but I haven't investigated that.)
Post a Comment for "Get Multiple Corresponding Values From Different HTML Tags To Use In A Function"