Instead of retrieving the singleton for the GoogleAuth library and setting up the client in my login page controller, I had to initialize it in the index.html file:
<script src="https://apis.google.com/js/api:client.js?onload=start" async defer></script> <script> function start() { gapi.load('auth2', function() { auth2 = gapi.auth2.init({ client_id: 'myAppID', cookiepolicy: 'single_host_origin' }); }); } </script>
This solved the problem of logging out. However, if the login page has been updated, its controller logic will be executed before gapi.auth2 is determined, and it would be impractical to successfully attach the click handler to the login button.
To avoid this - although this was not an elegant solution, I used $ interval until gapi.auth2 initialized:
waitForAuth2Initialization = $interval(function () { console.log("Checking..."); if (!gapi.auth2) return; console.log("Ok, gapi.auth2 is not undefined anymore"); var auth2 = gapi.auth2.getAuthInstance();
EDIT: another possible solution is to use the promise callback for the controller logic to wait until the promise is resolved, until the Google API is fully loaded and gapi.auth2 ready to use. This can be done if:
<script src="https://apis.google.com/js/api:client.js?onload=start" async defer></script> <script> gapiPromise = (function () { var deferred = $.Deferred(); window.start = function () { deferred.resolve(gapi); }; return deferred.promise(); }()); auth2Promise = gapiPromise.then(function () { var deferred = $.Deferred(); gapi.load('auth2', function () { auth2 = gapi.auth2.init({ client_id: 'myAppID', cookiepolicy: 'single_host_origin' }).then(function () { deferred.resolve(gapi.auth2); }); }); return deferred.promise(); }); </script>
And then in the controller:
auth2Promise.then(function () { console.log("Ok, gapi.auth2 is not undefined anymore"); var auth2 = gapi.auth2.getAuthInstance();
But the disadvantage of this approach is that it is slower (it takes twice as long to attach a click handler) than the first, using $interval .