Search code examples
angulartypescriptangular-routingangular-route-guards

How to access route params in route guard clause in Angular 7?


I have an Angular 7 app in which I have a route like this

{ path : 'forgot-password/:resetHash/:email', 
  component : ForgotPasswordComponent, 
  canActivate : [ForgotPasswordPageGuard]},

Now I tried to access this route's params in it's route-guard but I didn't get route params in guard. Here is my forgotpassword.route.guard.ts

constructor(private _utilityService: UtilitySerivce, private _dataService: DataService, private _const: Constants, private _router: ActivatedRouteSnapshot) {
}

canActivate = (): boolean => {
    console.log('in link expiry guard')
    let userEmail = this._router.paramMap.get('email');
    let isAllow = false;

    console.log('params : ', userEmail)
    userEmail = this._utilityService.decryptMsgByCryptoJs(userEmail);
    console.log('user email : ', userEmail)
    this._dataService.post(this._const.userResetPasswordLinkExpiry, { email: userEmail }).subscribe(resp => {
        if (resp.success) {
            isAllow = true;
        } else {
            isAllow = false;
        }
    })
    if (isAllow) {
        return true;
    } else {
        this._utilityService.navigate('/login');
        this._dataService.exhangeResetPasswordObsMsg({ event: 'linkExpired' });
        return false;
    }
}

But it's giving this error

enter image description here

What am I doing wrong?


Solution

  • canActivate takes the ActivatedRouteSnapshot as its first parameter, so add that to your function.

    export class MyGuard implements CanActivate {
      canActivate(route: ActivatedRouteSnapshot): boolean => {
        const email = route.paramMap.get('email');
    
        // the rest of the implementation
      }
    }
    

    CanActivate interface from the docs

    interface CanActivate {
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
        Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
    }
    

    EDIT

    If you want to make an HTTP request inside your guard, you return Observable<boolean> instead. You can see that this is permitted from the interface.

    export class MyGuard implements CanActivate {
      constructor(private http: HttpClient) {}
    
      canActivate(route: ActivatedRouteSnapshot): Observable<boolean> => {
        const email = route.paramMap.get('email');
    
        return this.http.get('some url').pipe(
          // map response to some boolean value that determines the permission
          map((response): boolean => true)
        );
      }
    }