I'm a little confused by how Angular routes treat the observables that a guard returns. Take the following route guard:
export class AuthenticationGuard implements CanActivate {
constructor(private sessionQuery: SessionQuery, private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
const loginPage = this.router.parseUrl('/login')
return this.sessionQuery.loggedIn$.pipe(
map((loggedIn: boolean): boolean | UrlTree => {
console.log('loggedIn emitted: ', loggedIn)
return loggedIn ? true : loginPage
})
)
}
}
The guard returns an observable that maps this.sessionQuery.loggedIn$
to either true
if the value is true
or loginPage
if false
.
However, I would expect that the route guard would subscribe to the observable: this.sessionQuery.loggedIn$
observable so that when it re-emits, the logic in the route-guard is re-evaluated.
However testing appears to show that it doesn't. If I subscribe to this observable elsewhere in the app I can see it re-emit but the console.log
call I've put in the code above doesn't fire.
I would like the route guard to trigger an automatic logout when the loggedIn$
observable emits false
.
If the route isn't subscribing the the guard then what's the point in the guard returning an observable in the first place? I feel like there's something I'm missing here...