rubenCodeforges / ng-gapi

ng-gapi a Google api module for Angular 6+

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using getAuth in a route guard prevents ngZone from working correctly.

RobertAKARobin opened this issue · comments

It seems when I use getAuth in a route guard, this._ngZone.onStable.asObservable() does not emit correctly.

Below is an example, also available at https://github.com/RobertAKARobin/ng-mat-select-weirdness.

import { Component, Injectable, NgModule, NgZone } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ActivatedRouteSnapshot, CanActivate, RouterModule, RouterStateSnapshot } from '@angular/router';

import { Observable, of } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { GoogleApiModule, GoogleAuthService, NG_GAPI_CONFIG } from 'ng-gapi';

import { googleClientId } from 'src/environments/.google'; // e.g. 123abcxyz.apps.googleusercontent.com

@Component({
  selector: 'app-root',
  template: `<router-outlet></router-outlet>`,
})
export class AppComponent {}

@Component({
  template: `<button (click)="didClick()">Click me</button>`
})
export class ViewComponent {
  constructor(
    private ngZone: NgZone,
  ) { }

  didClick() {
    this.ngZone.onUnstable.pipe(take(1)).subscribe(() => console.log('unstable'));
    this.ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe(() => console.log('microtask empty'));
    this.ngZone.onStable.pipe(take(1)).subscribe(() => console.log('stable'));
    this.ngZone.onError.pipe(take(1)).subscribe(() => console.log('error'));
  }
}

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(
    private googleAuth: GoogleAuthService,
  ) {
  }

  public canActivate(): Observable<boolean> {
    return this.googleAuth.getAuth().pipe(map(() => true));
  }
}

@NgModule({
  declarations: [
    AppComponent,
    ViewComponent,
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: '',
        canActivate: [AuthGuard],
        component: ViewComponent,
      },
    ]),
    GoogleApiModule.forRoot({
      provide: NG_GAPI_CONFIG,
      useValue: {
        client_id: googleClientId,
        discoveryDocs: ['https://analyticsreporting.googleapis.com/$discovery/rest?version=v4'],
        scope: 'profile openid',
      },
    }),
  ],
  bootstrap: [AppComponent],
})
export class AppModule { }

@RobertAKARobin Hi , check out the Auth Service https://github.com/rubenCodeforges/ng-gapi/blob/master/src/GoogleAuthService.ts

as you can see it has nothing to do with ngzone , it is pure rxjs

That's why I'm surprised: I don't see why routes should be involved. But the missing component of mat-select is that this._ngZone.onStable.asObservable() is not emitting any values. If in my guard I replace this:

return this.googleAuth.getAuth().pipe(map(() => true));

...with this:

rxjs.timer(100).pipe(map(() => true));

...then everything works as expected.

I've updated my code above to remove mat-select, since it doesn't really have anything to do with it — it's solely an issue of ng-gapi conflicting with NgZone.

Well, if I cast this to a Promise...

return this.googleAuth.getAuth().pipe(map(() => true)).toPromise();

...then it works.

@RobertAKARobin very intresting )))

Having the same problem with Angular 9 while also using this library with NgRx. Issue was indeed resolved by casting to a promise. I tried other fixes but I guess I will use this one for now.

I also find some related issues here:

google/google-api-javascript-client#353
#47

Having the same problem with Angular 9 while also using this library with NgRx. Issue was indeed resolved by casting to a promise. I tried other fixes but I guess I will use this one for now.

I also find some related issues here:

google/google-api-javascript-client#353
#47

this could be related to #83