Why Angular guards behave differently when using @select from @ angular / redux-store

  • I have a corner installation that uses two guards. canLoad and canActivate
  • both get the same observable from @ angular-redux / store via @select

Question : Why canActivate works with observable, @select returns canLoad and since then canLoad interrupted all routing? What is the difference between the two guards?

Related Angular Problem: https://github.com/angular/angular/issues/18991

auth.guard.ts

 @Injectable() export class AuthGuard implements CanLoad, CanActivate { @select() readonly authenticated$: Observable<boolean>; // @angular-redux/store canLoad(): Observable<boolean> | boolean { // return true; // works return this.authenticated$; // ERROR: all routing stops from and to the current page } canActivate(): Observable<boolean> | boolean { // return true; // works return this.authenticated$; // works } } 

application-routing.module

 const routes: Routes = [ { path: '', component: SomeAComponent, pathMatch: 'full' }, { path: 'someb', component: SomeBComponent, canActivate: [ AuthGuard ], }, { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule', canLoad: [ AuthGuard ] }, { path: '**', redirectTo: '/' } ]; 
+8
source share
2 answers

I had the same problem, so to solve it and let it work both in CanLoad and CanActivate, you have to add the take (1) operator

 @Injectable() export class AuthGuard implements CanLoad, CanActivate { @select() readonly authenticated$: Observable<boolean>; // @angular-redux/store canLoad(): Observable<boolean> | boolean { // return true; // works return this.authenticated$.pipe(take(1)); } canActivate(): Observable<boolean> | boolean { // return true; // works return this.authenticated$; } } 
0
source

I just ran into the same problem and I think this is a bug in angular. I ended up just rewriting my guard to save a local variable, which is populated with an Observable subscription. I am using ngrx / store here.

 @Injectable() export class MustBeAuthenticatedGuard implements CanActivate, CanLoad { constructor(private store: Store<fromAuth.State>) { store.select(fromAuth.authenticated) .subscribe((authenticated) => { this.authenticated = authenticated; }); } private authenticated: boolean canLoad(): boolean { return this.isAuthenticated(); } canActivate(): boolean { return this.isAuthenticated(); } private isAuthenticated() { if (!this.authenticated) { this.store.dispatch(new SignIn()); } return this.authenticated; } } 
-1
source

Source: https://habr.com/ru/post/1271506/


All Articles