fbence
fbence

Reputation: 2153

angular service not working as exp

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

Answers (1)

Martin Adámek
Martin Adámek

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

Related Questions