Search code examples
angularhttp

Angular HttpInterceptor and HttpClientModule causing infinite requests


I wrote an interceptor to grab a token I send from my server and add it to subsequent requests:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private store: Store) {}
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return this.store.select(selectUser).pipe(
      switchMap((user) => {
        if (user && user.token) {
          const authRequest = req.clone({
            setHeaders: {
              Authorization: `Bearer ${user.token}`,
            },
          });
          return next.handle(authRequest);
        }
        return next.handle(req);
      })
    );
  }
}

As per Angular recommendations, I wrote a separate provider for this interceptor:

import { Provider } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from '../http-interceptors/authInterceptor';
export const authInterceptorProvider: Provider = {
  provide: HTTP_INTERCEPTORS,
  useClass: AuthInterceptor,
  multi: true,
};

and then provided it to my base component (I'm using the standalone API, so AppComponent is kind of my main):

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(HttpClientModule),
    authInterceptorProvider,
    provideState(feedFeature),
    provideState(authFeature),
    provideStore(),
    provideEffects(feedEffects, authEffects),
    provideRouter(appRoutes),
    provideHttpClient(),
    provideStoreDevtools({
      maxAge: 25,
      logOnly: !isDevMode(),
      autoPause: true,
      trace: false,
      traceLimit: 75,
    }),
  ],
});

The behavior is this, if I remove the line:

    importProvidersFrom(HttpClientModule)

the interceptor doesn't work at all, but I do add it, my browser ends up making infinite requests with the interceptor working (I added a console.log).

I checked the request headers and the Auth headers aren't being sent either (user && user.token both exist, the console.log was inside the if statement)

Does anyone know why infinite requests are being sent? And/or why the header isnt being set?

Also, I'm not the best Angular especially with the standalone API, I'm pretty sure I'm doing something wrong with adding both:

importProvidersFrom(HttpClientModule) and provideHttpClient()

Solution

  • If this.store.select(selectUser) is making an API call to get the data, it will again call the interceptor, leading to an infinite loop.

    This was solved earlier by Oscar. By making the API call using HttpBackend this will skip calling the interceptor when an API call is made.

    So the solution will be the code inside this.store.select(selectUser) should use HttpBackend instead of HttpClient which will bypass the interceptor call and prevent the infinite loop!


    And also provideHttpClient() is alone enough to use the HttpClientMoudule providers!


    Also note you can also go for a interceptorFn instead of the old style of creating a class for an interceptor!