Search code examples
angularrxjsangular-routerangular-router-guards

Returning an Observable<boolean> from canActivate method and redirect on false


I have been searching for a solution with no luck. I need to call the server if a user is authorized and i need canActivate method to wait for the result for that call. But i can`t seem to put pieces together. Below is my code, my question is in the comments of the code.

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {

    let user: EUser = new EUser();
    user.sessionId = localStorage.getItem("sessionId");

    //I am not sure how to implement this part. 
    // I need to recieve the response and get user.isAuthorized value and return it
    // as an observable. 
    this.authenticationService.isAuthorized(user).subscribe((user)=>{
        //Here i need to get user.isAuthorized and 
        //if the value is false, i need to navigate to login with this.router.navigate['login'] and return it. 
        //if the values it true, i need the code continue as it is. 
    });

  }

AuthenticationService

isAuthorized(user:EUser){
    return this.http.post(ConnectionHelper.SERVER_URL+
          ConnectionHelper.USER+ConnectionHelper.ISAUTHORIZED,user).map(res => res.json());
}

Solution

  • Your approach is correct, you just need to map the server response to a bool value. For example:

    export interface AuthState {
        username:string;
        sessionId:string;
        isAuthorized:boolean;
    }
    
    isAuthorized(user:EUser): Observable<AuthState> {
        return this.http.post(ConnectionHelper.SERVER_URL+
              ConnectionHelper.USER+ConnectionHelper.ISAUTHORIZED,user)
        .map(res => res.json());
    }
    
    // Inject Router instance in the constructor of the guard class
    // import required rxjs operators
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        let user: EUser = new EUser();
        user.sessionId = localStorage.getItem("sessionId");
        return this.authenticationService.isAuthorized(user)
        .map(user => user.isAuthorized)
        .do(auth => {
          if(!auth){
             this.router.navigate(['/login']);
          }
        });
    }