Search code examples
angularangular7rxjs6angular-http-interceptors

Request is being fired infinitely when using observable in http interceptor


I have an issue with an http interceptor that depends on an observable. The whole thing ends up in an endless loop calling the same URL over and over again. However, I've searched for other solutions similar to mine (see e.g. Async HTTP Interceptors with Angular 4.3) and I can't see any big difference except for a different rxjs version. The interceptor looks as follows:

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {

  constructor(private loginSvc: LoginService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {    
    return this.loginSvc.currentUser$.pipe(
      mergeMap(x => {
        if (x) {
          console.log("User is authenticated, usually I would add a bearer token to the request here...");
        }
        return next.handle(req);
      })
    );
  }
}

Can someone point out my mistake I've made in this Angular http interceptor? You can see the whole working example here:

https://stackblitz.com/edit/angular-cazgsa?file=src%2Fapp%2Fservices%2Fmy-http-interceptor.service.ts

The setup is as follows:

  1. login.service.ts: this service encapsulates the authenticated user. It does this via a BehaviorSubject and an corresponding Observable. Initially, the subject is initialized with null which indicates a not logged in user.
  2. login.component.ts line line 17: as soon as the route /login is opened we're simulating a request which should authenticate a user. The request simply returns a user from jsonplaceholder which simulates a successful login.
  3. We're populating the user via LoginService so that all interested parties / observers get informed about the newly signed in user. One of these interested parties is the http interceptor.

In order to reproduce the issue open the http interceptor on StackBlitz and uncomment the lines as described there. In the developer console you'll see repetitive log messages which appear in an endless loop. Watch out: if you wait too long it leads to a crashing browser tab / window! So if you uncomment quickly comment out the lines again after you were able to re-produce the issue! On StackBlitz you can simply use the shortcut STRG + / to toggle comments on multiple lines!

Thanks a lot in advance!


Solution

  • I debugged your code.

    When your http request completes you push new value to a user subject (method signIn). Your interrupter stream dependent on currentUser$, as soon as new user value arrives, interrupter start all over again. I fixed interrupter to avoid this issue, and stop depending on current user.

    https://stackblitz.com/edit/angular-vbca4p?file=src%2Fapp%2Fservices%2Fmy-http-interceptor.service.ts