I am trying to implement UrlTree
to redirect user if guard fails.
this.authService.isAuthenticated()
returns observable.
The following does not work but it does console false
.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree {
this.authService.isAuthenticated().subscribe(isAuthenticated => {
if (isAuthenticated) {
return true;
} else {
console.log(isAuthenticated);
return this.router.createUrlTree(['auth/sign-in']);
}
});
return false;
}
But the following works if I remove subscription:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree {
return this.router.createUrlTree(['auth/sign-in']);
}
You cannot return from inside subscribe (in any case). Route guard can return a boolean or an observable of a boolean. So in your case you need to return an observable of boolean. Worth mentioning also, in your current code, since this is async, what you are currently returning is always false
no matter the logged in status, why? It takes x amount of time to get the authenticated status, so false
is returned every time, angular does not wait for the response, just moves on to the next code available, which is return false;
in your current code.
So, as said, return an observable, i.e use map
instead of subscribe
:
import { map, take } from 'rxjs/operators';
// ....
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.isAuthenticated()
.pipe(
take(1),
map(isAuthenticated => {
if (isAuthenticated) {
return true;
}
// no need for else, if above is truthy, further code is not executed
this.router.createUrlTree(['auth/sign-in']);
return false;
})
);
}