Search code examples
angularangular-guards

Is there a way to redirect if from within Guard in Angular when using asynchronous method to validate?


In my Angular(6.x.x) project, I am implementing a Guard on certain routes that should redirect to '/login' if it fails. The Guard, relies on an asynchronous method in AuthService for validating the user.

// AuthService
checkLogin(): Observable<boolean> {
  return this.http
    .get<boolean>(`${this.apiUrl}/users/autologin`)
    .pipe(
      map(result => result === true),
      catchError(error => of(false))
    );
}

// AuthGuard
canActivate(next: ActivatedRouteSnapshot, 
  state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.checkLogin();
}

How do I achieve this?

Note: I know how to do it if the code within canActivate is synchronous.

Code sample: https://stackblitz.com/edit/angular-async-guard-redirect?file=src%2Fapp%2Fapp.module.ts


Solution

  • You can add a tap into the Observable pipe in the AuthGuard, like so:

    return this.authService.checkAuthentication().pipe(
      tap(authenticated => {
        if (!authenticated) {
          // Add your redirect in here
        }
      })
    );
    

    This way, you can react to the Observable's value before you return it.