Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • I have an Angular setup that uses two guard. canLoad and canActivate
  • both get fed with the same observable from the @angular-redux/store via @select

Question: Why does canActivate work with the observable that @select returns while canLoad breaks all routing from then on? What is the difference between the two guards?

Related angular issue: 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
  }

}

app-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: '/'
  }
];
like image 249
Markus Avatar asked Sep 04 '17 16:09

Markus


1 Answers

The same issue I had, so to resolve it and let working in both CanLoad and CanActivate, you should add operator take(1)

@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$; 
  }

}
like image 169
Oleg Avatar answered Oct 23 '22 11:10

Oleg