Search code examples
angulartypescriptroutesangular-httpclientangular-http-interceptors

How to use provideHttpClient with route-specific interceptors in Angular?


I'm trying to set up provideHttpClient in Angular v19 to use route-specific interceptors, but I'm encountering an issue where no requests are intercepted.

My Setup:

I have a default ApplicationConfig for my app:

// Default App Configuration
export const appConfig: ApplicationConfig = {
    providers: [
        // Other default Angular providers
        provideHttpClient(),
        provideRouter(routes),
    ],
};

In addition, I have lazy-loaded routes where I provide route-specific interceptors:

export const routes: Routes = [
    // Lazy-loaded admin and chat feature routes
    {
        path: 'admin',
        title: 'Admin Area',
        providers: [
            provideHttpClient(withInterceptors([adminAuthInterceptor]), withRequestsMadeViaParent()),
        ],
        loadChildren: () => import('@features/admin/admin.routes').then(m => m.adminRoutes),
    },
    {
        path: 'chat',
        title: 'Chat Area',
        providers: [
            provideHttpClient(withInterceptors([userAuthInterceptor]), withRequestsMadeViaParent()),
        ],
        loadChildren: () => import('@features/chat/chat.routes').then(m => m.chatRoutes),
    },

    // Default route redirects
    // ...
];

And a sample interceptor:

export const adminAuthInterceptor: HttpInterceptorFn = (req, next) => {
    console.log('adminAuthInterceptor: Request intercepted:', req);
    return next(req); // Let the request pass through unchanged
};

Problem:

With this setup, no requests are intercepted by adminAuthInterceptor or userAuthInterceptor.

Question:

How can I correctly configure provideHttpClient to ensure that the appropriate interceptor is applied to requests based on the active route?

The interceptors should check if the authentication token is valid:

  • adminAuthInterceptor for the admin routes.
  • userAuthInterceptor for the chat routes.

Additional Context:

  • My API services are generated using openapi-generator-cli.
  • Components communicate with handwritten wrapper services that call the generated API services internally.
  • I want all requests made under the admin route (lazy-loaded adminRoutes) to be intercepted by adminAuthInterceptor.
  • Similarly, requests under the chat route (chatRoutes) should be intercepted by userAuthInterceptor.

Solution

  • I believe that my issue was with Angular's Dependency Injection setup. As I've mentioned in my question, I generated the API services using the openapi-generator-cli. By default, these services are configured with providedIn: 'root'. Similarly, all of my custom services used providedIn: 'root' as I tend to use it by default.

    As a result, all of my services were registered at the root level. This caused a problem when I tried to provide these services in a child route—they would always fall back to the root-level service since they were already registered there. At least that's what I would understand how Angular's dependency injection works.

    To resolve this, I removed the providedIn: 'root' setting from all the services. Instead, I explicitly provide each service only in the routes where they are needed. This approach not only fixes the issue but also aligns better with the intended use case, resulting in a cleaner and more modular design.