1
votes

I'm playing around with Angular interceptor and i wanted to re route if the response status is 401 and below is what i've tried .

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {

  constructor(private _localStorageService: LocalStorageService, private _router: Router, private _location: Location) { }


  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.includes("/login")) {
      return next.handle(req);
    }
    let authToken: LocalStorage = this._localStorageService.getItem('auth-token');
    if (authToken) {
      return next.handle(
        req.clone({
          headers: req.headers.append('Authorization', 'jwt ' + authToken.value)
        })
      ).pipe(tap((response: HttpResponse<any>) => {
        console.log(response);
        if (response instanceof HttpResponse) {
          if (response.body.status == 401) {
            this._router.navigate([Routes.LOGIN]);
            return response;
          }
        }
      }));
    }
    this._router.navigate(['/login']);
  }
}

This process is working , but whenever the route is changed i get this in the chrome dev console : ERROR You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

How do i prevent this ? and what am i doing wrong ?

2
It is very similar to NullPointerException .Antoniossss
did you try debug issue from what line of code?Hien Nguyen

2 Answers

2
votes

This error always refers to a missing or wrong return value, in your case, at some point, the intercept method does not return an observable but either nothing or something else instead. The observable is then being used by Angular internally, and because it is not an observable, it fails. E.g. if your authToken is undefined, you return nothing, so the result of the intercept method is undefined.

0
votes

Thank you @Julien For pointing me to the right direction. After looking at the answer , i did a bit more digging in search of solution and the below is the solution that worked for me

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {

  constructor(private _localStorageService: LocalStorageService, private _router: Router, private _location: Location) { }


  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.includes("/login")) {
      return next.handle(req);
    }
    let authToken: LocalStorage = this._localStorageService.getItem('auth-token');
    if (authToken) {
      return next.handle(
        req.clone({
          headers: req.headers.append('Authorization', 'jwt ' + authToken.value)
        })
      ).pipe(tap((response: HttpResponse<any>) => {
        console.log(response);
        if (response instanceof HttpResponse) {
          if (response.body.status == 401) {
            this._router.navigate([Routes.LOGIN]);
            return response;
          }
        }
      }));
    }
    this._router.navigate(['/login']);
    return empty();
  }
}

If anyone comes across this issue refer : Angluar2 routing inside http interceptor

The accepted answer does not use the http interceptor but there is another answer that uses interceptor

The Solution that i used is just return an empty observable using empty()