0

Problem with returning value in asynchronous http request.

How to wait for subscribe?

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    if (this.auth.currentUser) {
      return true;
    } else {
      this.auth.getUser()
        .subscribe(resp => {
          if (this.auth.currentUser) {
            return true;
          } else {
            this.router.navigate(['login'], {
              queryParams: {
                returnUrl: state.url
              }
            });
            return false;
          }
        })
    }
  }

No result is returned when refreshing page and I m redirect to main page.

  • 1
    Probably a duplicate of https://stackoverflow.com/questions/38425461/angular2-canactivate-calling-async-function and https://stackoverflow.com/questions/41377014/angular-2-canactivate-async – Ján Halaša Aug 03 '17 at 08:16

1 Answers1

0

You do not return anything in the 'else' path :

canActivate(
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) {
  if (this.auth.currentUser) {
    return true;
  } else {
    // This path do not return any value !

    this.auth.getUser()
      .subscribe(resp => {
        if (this.auth.currentUser) {
          // This return is the return of your subscription callback function, not the canActivate one !
          return true;
        } else {
          this.router.navigate(['login'], {
            queryParams: {
              returnUrl: state.url
            }
          });
          // Same here
          return false;
        }
      })
  }
}

You need to return a value (boolean, Promise or Observable) in the second path :

canActivate(
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) {
  if (this.auth.currentUser) {
    return true;
  } else {
    return this.auth.getUser()
      .map(resp => {
        if (this.auth.currentUser) {
          // This return is the return of your subscription callback function, not the canActivate one !
          return true;
        } else {
          this.router.navigate(['login'], {
            queryParams: {
              returnUrl: state.url
            }
          });
          // Same here
          return false;
        }
      })
      .first();
  }
}

Using map with your callback that return a boolean, you return an Observable.

Guillaume Nury
  • 373
  • 3
  • 7