Angular2 return route. Observed <bool> how to handle errors

I have route protection as shown below

@Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router, private authenticationSvc: AuthenticationService) { } canActivate(): Observable<boolean> { return this.authenticationSvc.getAuthenticatedUser().map( r => { if (this.authenticationSvc.isAuthenticated()) { // logged in so return true return true; } this.router.navigateByUrl('/login'); return false; }) } 

The problem is that sometimes getAuthenticatedUser returns 401, and I have an HTTP interceptor that processes 401 and redirects to the login page. The problem is that this .map is never resolved because the HTTP request causes an error and the angular router gets stuck in this first routing request and cannot handle the subsequent request from the interceptor. How can I handle this error and return the returned Observable solution to false and keep moving?

  getAuthenticatedUser() { let getUserObservable = this.http.get(ApiUrl + 'security/getAuthenticatedUser') .map((res: any) => res.json()) .share() //Get the result for the cache getUserObservable.subscribe( r => { if (r.success) { this.authenticatedUser = r.result.user; } }); //return the observable return getUserObservable; } 

and http-intercepter below

 export class HttpInterceptor extends Http { authSvc: AuthenticationService; lastClicked: any = 0; constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private injector: Injector) { super(backend, defaultOptions); } request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.request(url, options)); } get(url: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.get(url, options)); } post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.post(url, body, this.getRequestOptionArgs(options))); } put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.put(url, body, this.getRequestOptionArgs(options))); } delete(url: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.delete(url, options)); } getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs { if (options == null) { options = new RequestOptions(); } if (options.headers == null) { options.headers = new Headers(); } options.headers.append('Content-Type', 'application/json'); return options; } intercept(observable: Observable<Response>): Observable<Response> { return observable.catch((err, source) => { //If we get a 401 from the api that means out FormsAuthenticationTicket has expired, clear the auth cookie and navigate back to terms page if (err.status == 401) { this._router.navigateByUrl('/login'); } return Observable.throw(err); }); } 
+7
source share
1 answer

You can catch errors and return an Observable<bool> as follows:

 @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router, private authenticationSvc: AuthenticationService) { } canActivate(): Observable<boolean> { return this.authenticationSvc.getAuthenticatedUser().map( r => { if (this.authenticationSvc.isAuthenticated()) { // logged in so return true return true; } this.router.navigateByUrl('/login'); return false; }) .catch((error: any) => { this.router.navigateByUrl('/login'); return Observable.of(false); }); } 
+9
source

Source: https://habr.com/ru/post/1264910/


All Articles