I am currently building a route guard that checks if my client is authenticated. Since I am using http only cookies I have to send a request to my server which then returns if the cookie is valid or not. This is the code for my guard:
export class AuthGuard implements CanActivate {
constructor (private auth: AuthService){}
async canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Promise<boolean> {
let isAuthenticated : boolean = false;
await this.auth.getAuthStatus().subscribe(
res => {
if(res.status == 200){
isAuthenticated = true;
}
})
console.log(isAuthenticated)
return isAuthenticated;
}
}
and the service is just a simple http call:
getAuthStatus(): Observable<HttpResponse<any>>{
return this.http.post(environment.server environment.routes.authRoutes.status, "", {
withCredentials: true,
observe: 'response'
})
}
The problem I am facing is that my guard has to return a boolean for the router, and since I am using .subscribe it returns false since it returns siAuthenticated before I .subscribe finishes. I tried adding await and returning a promise, but either it does not work in my case or I did not use it correctly. I tried finding a solution in different posts, but none of them worked for me (Or I just didnt understand them properly and implemented them in the wrong way).
Thank you
CodePudding user response:
for newer RxJS version you can write
const response = await lastValueFrom(this.auth.getAuthStatus());
and for older
const response = await this.auth.getAuthStatus().toPromise();
CodePudding user response:
await
needs a Promise
So you can use toPromise()
method of Observable
and change the return type of getAuthStatus()
.
But as @ShamPooSham mentioned in the comment, I also recommend returning Observable
instead of a Promise
from the guard.
getAuthStatus(): Promise<HttpResponse<any>>{
return this.http.post(environment.server environment.routes.authRoutes.status, "", {
withCredentials: true,
observe: 'response'
}).toPromise()
}
await this.auth.getAuthStatus().then(res => {...})