Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Route navigation inside HttpInterceptor

Is it possible to navigate to a specific route when a 401 error is catched, inside an HttpInterceptor?

What I've tried to do is:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
​    return next.handle(req)
        .do((event: HttpEvent<any>) => {}, (error: any) => {
             if (error instanceof HttpErrorResponse) {
                 if (error.status === 401) {
                     this.router.navigate(['/signin']);
                 }
             }
         });
​}

But nothing is happening.

I can redirect to signin page only if using

window.location.href = '/signin';

instead of

this.router.navigate(['/signin']);
like image 803
manuel Avatar asked Nov 24 '17 16:11

manuel


People also ask

What is dynamic routing in angular?

Dynamic Routing means, that the route configuration of a module can vary at each load depending on the logic you define for the loading. The main trick is to use the ROUTES InjectionToken which is a low-level API for the router configuration.

What is interceptor in HTTP request?

What is an Angular HTTP Interceptor. The angular interceptor is a medium connecting the backend and front-end applications. Whenever a request is made, the interceptors handle it in between. They can also identify the response by performing Rxjs operators.

How do I use HttpInterceptor?

HTTP Interceptors is a special type of angular service that we can implement. It's used to apply custom logic to the central point between the client-side and server-side outgoing/incoming HTTP request and response. Keep in mind that the interceptor wants only HTTP requests.

What is angular route Guard?

Angular route guards are interfaces provided by Angular which, when implemented, allow us to control the accessibility of a route based on conditions provided in class implementation of that interface. Here are some types of Angular guards: CanActivate, CanActivateChild, CanLoad, CanDeactivate and Resolve.


2 Answers

Yes it's possible, tried in Angular 4 & 5.

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import { AuthHelperService } from '../main/content/authentication/auth-helper.service';


@Injectable()
export class UnauthorizedInterceptor implements HttpInterceptor {

    constructor(private authHelperService: AuthHelperService, private router: Router ) {}


    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        return next.handle(request)
            .do((event: HttpEvent<any>) => {
                if (event instanceof HttpResponse) {
                    // If required, here we can do any stuff with the response getting from API.
                    console.log('Common place to handle 1 response');
                }
            })
            .catch(error => {
                if (error instanceof HttpErrorResponse) {
                    if (error.status === 401) {
                        //when the API service return any 401-Unauthorized error control come here, 
                        //Call logoutUser to clear and redirect to login page. 
                        console.log('Handle 401');
                        this.authHelperService.logoutUser();
                        //this.router.navigate(['auth/login']); //You can Navigate to the router directly, in this example it will be done in authHelperService.
                    }

                    return Observable.throw(error);
                }else{
                    return Observable.throw(error);
                }
            });

    }

}

Following is the service code, makesure to Resolve() in error case otherwise it will be in hang state:

getFaqs(): Promise<any[]>
{
    return new Promise((resolve, reject) => {

        const body = '';

        this.http.post('http://localhost:3000/faq/faqs', body)    
        //Map is a handler to parse the response, subscribe will get parsed value as the result. Error has been gloably handled, by HTTP Intercepter.
        .map((res:Response)=>res)  
        .subscribe(
            (result: any) => {
                //console.log('faq/faqs Service Response : ' + JSON.stringify(result));
                this.faqs = result.data;
                this.onFaqsChanged.next(this.faqs);
                resolve(this.faqs);        
            },
            (error)=>{
                console.log('ERROR CAME HERE');
                resolve();
            }
        );

    });
}
like image 108
Wasantha Wijayaratna Avatar answered Nov 15 '22 22:11

Wasantha Wijayaratna


Assigning to location.href is similiar to:

this.router.navigateByUrl('/signin');

The navigate method takes router commands not paths.

like image 30
André Werlang Avatar answered Nov 15 '22 21:11

André Werlang