Search code examples
angular-guards

Using a service in angular 4 guards


Please assist with angular guards, I have the following angular Guard below :

export class RoleGuard implements CanActivate {

 private role: any;
 constructor(private router: Router, private accountService: AccountService) 
 {}

   canActivate(
      next: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
   ): Observable<boolean> | Promise<boolean> | boolean {

     this.accountService.getUserRole().subscribe(res => this.role = res);
     if (this.role === 'admin') {
         return true;
     }
   return false;
 }
}

in the service:

  getUserRole(): Observable<Response> {
  const options = this.headers();
    return this.http.get(`${environment.ApiUrl}/Roles/getRole`,options)
  .map(res => res.json())
  .catch(res => Observable.throw(res.json()));
 }

I am trying to subscribe to the getUserRole() function, then assign the response to this.role but that is not happening, role is always undefined. when i do a ...subscribe(res => console.log(res)) i see the response data.


Solution

  • You have to wait the result of the async HTTP Request before check if can activate that route or not.

    Try returning a new Observable instead:

    canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {
    
        return new Observable(observer => {   
            //
            this.accountService.getUserRole().subscribe(role => {
                //
                if (role === 'admin') {
                    observer.next(true); // Allowing route activation
                } else {
                    observer.next(false); // Denying route activation                
                }
            }, err => observer.next(false)); 
        }); 
    }