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, ie 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;
})
);
}
Didnt know u need to redirect user so use this functions:
canActivate(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
return this.authService.isAuthenticated().pipe(
take(1),
map(user => !!user),
tap(loggedIn => {
if (!loggedIn) {
this.router.navigate(['/login'])
}
})
);
}
@AJT82 answer didn't work for me in Angular 8. Returning a UrlTree with parseUrl
and return a true
is the only way it works.
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.authService.auth$.pipe(
map((authState: AuthState) => {
console.log('=========root guard=============');
if (!authState.isLoggedIn) {
return this.router.parseUrl('/auth/login');
}
if (state.url === '' || state.url === '/') {
if (authState.accessGroups.includes(AccessGroup.ADMIN)) {
return this.router.parseUrl('/post/list');
}
if (authState.accessGroups.includes(AccessGroup.REEF)) {
return this.router.parseUrl('/reef');
}
}
return true;
})
);
And I don't really understand why returning the UrlTree is not enough. If I do not return the true
the Router will be blocked. Very strange.
Setting the UrlTree and then returning True didn't work either. Only returning the UrlTree
and return true
works for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.