API call in canactivate method in Angular

You can also try like this:

canActivate(): Observable<boolean> | Promise<boolean> | boolean {
    return new Promise(res => {
        this.authservice.isUserAuthenticatedbyType("type1").subscribe(
            (data) => {
                if (data === true) {
                    res(true);
                } else {
                    this.router.navigate(['/']);
                    res(false);
                }
            },
            (error) => {
                this.router.navigate(['/']);
                res(false);
            }
        );
    });
}

If you are using promise try something like this - main idea is to hold your routing until your Api call is done - I had the same issue, I have achieved it by returning Promise<boolean> on my route gaurds

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean{
    const self = this;
    const expectedType = "type1";
    retrun new Promise(res => {
      this.authservice.isUserAuthenticatedbyType(expectedType).then(
        function (data) {
          if (data === false) {
            console.log(data);
            self.router.navigate(['/'], { relativeTo: self.route });
          }
          res(data);
        },
        function (error) {
          self.router.navigate(['/']);
          res(false);
        }
      );
    });
  }

This method solved my issue - it waits until the API returns data and gives direction to the route

Hope it will work - Happy coding !!


You can achieve it like this:

Angular <= 7.0.0

public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  return this.authservice.isUserAuthenticatedbyType("type1").pipe(
    map(data => {
      if (data === false) {
        this.router.navigate(['/']);
        return false;
      }

      return !!data;
    }),
    catchError(() => {
      this.router.navigate(['/']);
      return of(false);
    }),
  );
}

Angular >= 7.1.0

Starting with Angular 7.1.0 (note that it's not in 7.0.x), you can also do this instead, which is shorter and more predictable if you have multiple guards:

public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  return this.authservice.isUserAuthenticatedbyType("type1").pipe(
    map(data => data === false ? this.router.parseUrl("/") : !!data)
    catchError(() => this.router.parseUrl("/")),
  );
}

Tags:

Angular