5

Can anyone help me out with why an asynchronous call inside an Angular guard would not activate the route after the result is returned from the call? I have tried a couple approaches utilizing promises and observables with limited luck. I also found this github issue specifically the albakov recommendation. It is important for me to note the snippets below execute. I see the console message in the console with all the correct values I also was able to break on my server side api call. The result is passed into the observable the canActivate guard returns, but the route is not activated as anticipated.

Service method with properties that calls the api and binds the _isAuthorized subject with the result:

private _isAuthorized: ReplaySubject<boolean> = new ReplaySubject(1);
get isAuthorized() { return this._isAuthorized.asObservable(); }

checkAuthority(id: number) {
    return this._http.get(this._apiUrl).toPromise().then((response) => {
        console.log(response + ' I resolved!');
        if (response.status === 200)
            this._isAuthorized.next(true);
    });

Consuming Guard Can Activate Method:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
  let id: number = this.getId();

  if (!this._oauthService.hasValidIdToken()) {
    this._router.navigate([`/login/${id}`]);
    return Observable.of(false);
  }

  this._myService.checkAuthority(id);
  return this._myService.isAuthorized.first();
}

No console errors of any kind occur the page just never routes after the resolution of the observable boolean value to true.

UPDATE The above code works if I change the re-direct to the protected (guarded) route from the login component to a hard redirect (ie: window.location.href) rather than a router.navigate call. Without this hard redirect from the login component, the router cancels navigation if I enable tracing, to the protected route after resolution of the api call.

Shawn
  • 869
  • 1
  • 9
  • 27

1 Answers1

6

Angular 2 - Routing - CanActivate work with Observable

Just return the observable(Observable<boolean>) in the guard and it will work!

Jan Wytze
  • 3,307
  • 5
  • 31
  • 51
  • You are right it should work that way but for some reason with the additional component of an OIDC re-direct back to a route that re-sends you to the page you were blocked from (while unauthorized) causes Navigation to be cancelled by the router. As mentioned above if you issue a hard refresh it works fine as it doesn't go through the landing url after being authorized. – Shawn Jul 20 '17 at 15:02
  • You are correct, there appears to be an issue with the OAuth/OIDC library I am using. – Shawn Jul 28 '17 at 12:48