0

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

aryaag
  • 110
  • 8

2 Answers2

1

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.

user184994
  • 17,791
  • 1
  • 46
  • 52
0

You can change authservice like this.

   // AuthService
checkLogin(): Observable<boolean> {
  return this.http
    .get<boolean>(`${this.apiUrl}/users/autologin`)
    .pipe(
      map(result => { if(result === true)
                        {
                            returrn true;
                        }
                        this.router.navigateByUrl('/login');
                        return false;
                        }),
      catchError(error => of(false))
    );
}
Dheeraj Kumar
  • 3,917
  • 8
  • 43
  • 80
  • I cannot do it in the Service as I might want to do some dynamic redirection in the Guard by first checking the `next.url` value from the ActivatedRouteSnapshot. – aryaag Sep 26 '18 at 15:57