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?
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.