Search code examples
angulartypescriptangular-routergoogle-api-js-client

Using Gapi with Angular - signOut().then() not running in right zone


I am adding Google sign in to my Angular project. I followed this SO question on getting gapi set up.

I then ran into a problem with running code outside the NgZone and remedied that with this SO question.

Signing in now works well. However, I've been having trouble getting sign out to work. The function itself works: Google signs the user out of my application. It's only noticeable when you reload the page and have to sign in again. However, the Angular portion of the code errors out. I get the following error:
Uncaught TypeError: Cannot set property 'token' of undefined

Where undefined should be this. Unfortunately, I've been unable to find any examples of signing out with Google in Angular. Every tutorial and example project I've seen on GitHub only signs the user in.

I've tried various combinations of arranging the code with ngZone.run(). I've also tried passing auth2.signOut().then() an Observable's next() function, but that yielded the same error. Passing ngZone.run() didn't work either and also yielded the same error.

// This code errors. I've tried putting ngZone.run() inside the  
// .then() as well with the same error of 'this' being undefined  

this.ngZone.run(() => {
    const auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
        auth2.disconnect();
        this.token = null;
        this.router.navigateByUrl('/pages/login');
    });
});


// This code works, it's in the component where the sign in with Google button is  

public onSignIn(googleUser) {
    this.ngZone.run(() => {
        const p = googleUser.getBasicProfile();
        const r = googleUser.getAuthResponse();
        <snipped for relevance, accessing this.* works here>
    });
}

Solution

  • Figured it out. You can make a variable to store this and pass that variable and use it in place of this.

    this.ngZone.run(() => {
        const self = this;
        const auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {
            auth2.disconnect();
            self.token = null;
            self.router.navigateByUrl('/pages/login');
        });
    });