Reputation: 2153
I am trying to put google login in a web app into an angular service, but I can't figure out what I am doing wrong.
Here is my service
angular.module('sensdogserver.services', [])
.service('AuthenticationService', function ($window,$http) {
console.log("service started")
gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
gapi.auth2.init(
{
client_id: 'CLIENT_ID',
}
);
});
this.googlelogin = function(){
var GoogleAuth = gapi.auth2.getAuthInstance();
GoogleAuth.signIn().then(function(googleUser){//request to sign in
var profile = googleUser.getBasicProfile();
username = profile.getName();
$window.localStorage['username'] = username;
googleUser = googleUser;
googletoken = googleUser.getAuthResponse().id_token;
console.log("google token: " + googletoken);
$http.get("/api/auth/google/token",{headers:{'id_token':googletoken}}).success(function(data){console.log(data)}).error(function(data){console.log(data)});
}
)};
this.googlesignout =function() {
var auth2 = gapi.auth2.getAuthInstance();
console.log("signing out: ", username);
auth2.signOut().then(function () {
googleUser = null;
googletoken = null;
username = null;
console.log('User signed out.');
});
}
var googleUser = null;
var googletoken = null;
var username = null;
this.googlelogin();
});
When I load the page, the console logs service started
as expected, but then I get an error TypeError: Cannot read property 'getAuthInstance' of undefined
. If I comment out the call to google login and call googlelogin
from a controller, after the page has loaded it works absolutely fine. What I don't understand is that I get the log message, so it seems the service is loaded and something runs, but not everything.
Upvotes: 0
Views: 86
Reputation: 18369
You should place the this.googlelogin();
call inside the gapi.load('auth2', ...)
callback. You are calling it before it is initialized.
angular
.module('sensdogserver.services', [])
.service('AuthenticationService', function ($window,$http) {
console.log("service started")
gapi.load('auth2', function() {
gapi.auth2.init({
client_id: 'CLIENT_ID',
});
console.log('gapi.load callback triggered');
this.googlelogin(); // call it here in the load callback
}.bind(this));
this.googlelogin = function(){
// ...
};
this.googlesignout = function() {
// ...
}
// ...
console.log('this will be printed before the gapi.load callback');
});
I added logging to the load callback and to that place you used to call the googlelogin
function to highlight the problem.
The gapi.load()
call is asynchronous (non-blocking) - when you call it, it will call the desired API, but will not wait for the response. The response will be available in the callback function, which will be triggered in another event loop (after the main program block, where the gapi.load()
function was called).
Take a look at this: https://developer.mozilla.org/cs/docs/Web/JavaScript/EventLoop, it should provide you with some basics about this. Calling gapi.load
is very similar to the example with setTimeout
.
Upvotes: 1