Chrillewoodz Chrillewoodz - 20 days ago 14
TypeScript Question

Angular 2 how to make auth guard work with observable

I'm trying to implement an auth guard to one of my routes but I can't get it to work since I'm not sure how to do it with an observable.

I use

ngrx/store
to store my token and then in the guard I fetch it using
this.store.select('auth')
, which fetches an object that looks like this (if you're logged in):

{
token: 'atokenstring',
isAuthenticated: true,
isPending: false
}


And the guard looks like this:

export class AuthGuardService implements CanActivate {

constructor(private router: Router, private store: Store<IStore>) {}

canActivate(): Observable<any> {

return this.store.select('auth').let((state: Observable<IAuthStorage>) => state.filter((auth: IAuthStorage) => !auth.isPending && auth.isAuthenticated)).map(
(auth: IAuthStorage) => {

if (!auth.isAuthenticated) {
return this.router.navigateByUrl('admin/login');
}
else {
return true;
}
}
);
}
}


Now, the problem appears to be that the guard returns an observable rather than a boolean value. Which causes the route not to render even if you get inside the
else
which returns
true
.

How can I make it so that the guard returns a boolean value rather than an observable?

Answer

Not sure if this still is the case but a while ago something like this was required

  canActivate(): Observable<any> {

    return this.store.select('auth').let((state: Observable<IAuthStorage>) => state.filter((auth: IAuthStorage) => !auth.isPending && auth.isAuthenticated)).map(
      (auth: IAuthStorage) => {

        if (!auth.isAuthenticated) {
          return this.router.navigateByUrl('admin/login');
        }
        else {
          return true;
        }
      }
    ).first(); // <<<=== added
  }

for the router only to wait for one event, not for the observable itself to complete.

first needs to be imported to be available.