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: