I've put an angular routing authguard to put my page. I've an api that checks if the token is valid and based on that I want to return true or false for further navigation.
But seems that in 'subscribe' I assign my 'result' flag true not persisting outside of the subscribe. Is 'result' variable in wrong scope here? How can I correct that? Please help me understand my mistake in below code.
canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const jwt = localStorage.getItem('jwt');
let result = false;
this.signinService.isSignedin(jwt).subscribe((res) => { // <---
console.log(res.json().message);
if (res.json().message === 'Token Valid') {
result = true;
console.log(result);
return true;
} else {
result = false;
return false;
}
}, (err) => { // <---
console.log(err);
result = false;
return false;
});
console.log('END' + result);
return result;}
The above code prints out on console in below order, which seems to be weird to me. Anyone can explain please?
ENDfalse
Token Valid
true
But seems that in 'subscribe' I assign my 'result' flag true not persisting outside of the subscribe.
I think you are not fully understanding how the interpreter will read and evaluate this code. Because the JavaScript event loop is never blocking, the interpreter will get to the subscribe block, make the request, and then continue along executing the code outside of the subscribe block without waiting for the response to come back. This is why "ENDfalse" is printed first. Then the response comes in and the callback function is executed with the line console.log(res.json().message);
printing "Token Valid" and
console.log(result);
returning true.
One way you could fix this might be to return the whole observable and then subscribe to in the place where you actually want to use the value of "result" (and in fact your function signature of canActivate shows that you should be returning an observable, not the data).
canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const jwt = localStorage.getItem('jwt');
return this.signinService.isSignedin(jwt);
}