Check out the code snippet I recently created:
kb.loadAsync('https://apis.google.com/js/client.js', 'onload', 'gapi').then(gapi => {
gapi.auth.authorize({
client_id: __GOOGLE_CALENDAR_API_KEY__,
scope: 'https://www.googleapis.com/auth/calendar',
immediate: true,
}, authResult => {
if(authResult && !authResult.error) {
gapi.client.load('calendar','v3', () => {
gapi.client.calendar.calendarList.list({
maxResults: 250,
minAccessRole: 'writer',
}).execute(calendarListResponse => {
let calendars = calendarListResponse.items;
console.log(calendars.map(cal => cal.summary));
});
});
} else {
console.log('unauthorized');
}
});
});
The kb.loadAsync
function that you see in action is what I built for loading Google APIs asynchronously. Here's its definition:
/**
* A utility function for asynchronous loading of Google APIs.
*
* @param {string} source
* @param {string} callbackParam
* @param {string=} globalName
* @returns {Promise}
*/
export function loadAsync(source, callbackParam, globalName) {
return new Promise((resolve,reject) => {
let callbackFunc = Math.random().toString(36);
window[callbackFunc] = () => {
resolve(window[globalName]);
delete window[callbackFunc];
};
let sep = source.includes('?') ? '&' : '?';
$script(`${source}${sep}${encodeURIComponent(callbackParam)}=${encodeURIComponent(callbackFunc)}`);
});
}
This function uses scriptjs. However, scriptjs' callback triggers too early as Google loads additional data after downloading client.js, requiring us to use Google's onload
parameter for proper functionality.
If you prefer using a bunch of <script>
tags, you can avoid these dependencies. Nevertheless, async functions offer a cleaner solution for me.