I'm trying to create a RouterGuard in Angular that gets a response from the backend about the User's login status. The problem is that the HTTP request returns a Subscription with async concrete values. How can I guarantee the Router will "wait" for the http call to be transformed into a real value and then be processed?
AlreadyLoggedRouterGuard:
export class AlreadyAuthIn implements CanActivate {
constructor(private clientService: ClientService,
private router: Router) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.clientService.isUserLogged()
.subscribe(
(response: Response) => {
let loginStatus = response.message;
if (loginStatus == 'not_logged') {
localStorage.clear();
return false;
} else {
return true;
}
});
}
Note: clientService.isUserLogged() is the http call, and will return a Observable.
This code already shows an Error saying that should not return a Subscription. Then I tried to assign the logic to a variable like:
let logged = this.clientService.isUserLogged().subscribe(...<logic>......)
if (logged) {
return false;
} else {
return true;
}
But that creates a new problem: race condition. The If statement is checked before the Subscription turns into a Boolean value, and the program processes the logic wrongly. Maybe we can solve this with a Promise?
You are now returning a subscription not the result of your request. Use a map function to turn the return type of your request into an Observable<boolean>
which will be used by angular to handle the route guard.
Try something like (untested)
export class AlreadyAuthIn implements CanActivate {
constructor(private clientService: ClientService,
private router: Router) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.clientService.isUserLogged()
.pipe(map((response: Response) => {
let loginStatus = response.message;
if (loginStatus == 'not_logged') {
localStorage.clear();
return false;
} else {
return true;
}
});
}