Angular4 Interceptor change response
Asked Answered
T

1

5

I have an auth HttpInterceptor:

import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, 
HttpRequest} from '@angular/common/http';
import {AuthService} from '../service/auth.service';
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';
import {Router} from '@angular/router';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private authService: AuthService,
              private router: Router) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authHeader = this.authService.getToken();
    const clone = req.clone({headers: req.headers.set('Authorization',authHeader)});
    return next.handle(clone).do(() => {
}, err => {
  console.log(err);
  if (err instanceof HttpErrorResponse && err.status === 401) {
    this.authService.clearToken();
    this.router.navigate(['/auth/signin']);
    return Observable.empty();
      }
    });
  }
}

This interceptor works fine, but when i'm getting 401 i'm redirecting user to login page, but the error still goes to the service, and in that service i'm showing error msg, and this msg showing at signin page. So i want to change response or do something in if (err instanceof HttpErrorResponse && err.status === 401) { block, to not returning error in this case.

return Observable.empty();

is not working

Tomi answered 20/9, 2017 at 19:5 Comment(0)
A
8

next.handle(clone).do() - this is what's causing such behavior. do() operator is intended only to provide side-effects, but it does not actually affect data flow and error handling in the observable pipe. Essentially it is saying "when this happens please do this and that and then continue as if there's no do() section at all". If you want to suppress errors then you need to use catch() operator.

Code would be almost the same:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService,
                private router: Router) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const authHeader = this.authService.getToken();
        const clone = req.clone({headers: req.headers.set('Authorization',authHeader)});
        return next.handle(clone).catch(err => { // <-- here
            console.log(err);
            if (err instanceof HttpErrorResponse && err.status === 401) {
                this.authService.clearToken();
                this.router.navigate(['/auth/signin']);
                return Observable.empty();
            }
            // we must tell Rx what to do in this case too
            return Observable.throw(err);
        });
    }
}
Available answered 20/9, 2017 at 19:12 Comment(2)
can you please write a small example with catch?Tomi
@user2870934, I edited my answer. Code is almost the same, you were very close.Available

© 2022 - 2024 — McMap. All rights reserved.