Search code examples
angularrxjsangular-guards

Angular how do I use await with .subscribe


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


Solution

  • 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 => {...})