I'm doing a basic authentication for users after login, but weird behavior is happening, where canActivate is returning false, even though it is being called in the right time.
in Login Component
private login() {
this.authService.login(this.loginForm.valid)
.subscribe((data: any) => { // no need for pipe and map
console.log("First");
this.router.navigate(['/app']);
})
}
in auth.service:
login({ username, password }: any): Observable<any>{
this.clearData();
const loginData = {
'username': username,
'password': password
};
return this.http.post(environment['baseURL'] + '/api/auth/login', loginData).pipe(
map(
(data: any) => {
if (data['token'] && data['user']) {
this.isLoggedIn.next(true);
this.token = data['token'];
localStorage.setItem('token', this.token);
localStorage.setItem('usermeta', JSON.stringify(this.userData));
return true;
} else {
return false;
}
},
(error: any)=>{
return of(false)
}
)
)
}
getToken(): string {
return this.token;
}
hasToken() {
return this.getToken() ? true : false;
}
in auth.guard.service
constructor(
private router: Router,
private authService: AuthService,) {
console.log("SECOND - canActivate") --> this is being printed on the success of the login call
}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
console.log(this.authService.hasToken(), ">> this.authService.hasToken() <<")
if (this.authService.hasToken()) {
return true;
} else {
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}
In console tab, it shows "First" then "Second - canActivate" which tells that the token has already took its value on success of the call, However, for some reason the value returned by hasToken() method is false

To be honest, I can't quite spot what's wrong but there's a few things I'd write differently, so I'll suggest those and hopefully it refactors the issue away. Also
console.logis async, so don't trust it to log in the correct order.When using RxJS I recommend leaning towards functional and not using static member variables to pass values around. You should aim to chain everything so you don't have any unexpected async side effects.
This is not tested but should be correct. Check the inline comments. Hope it helps.