Kay
Kay

Reputation: 19660

Angular - Interceptor not loading in a lazy loaded module

I have created an interceptor which appends a token to the authorization header only needed for API calls made within a feature lazy loaded module.

However, I don't think the interceptor is being called as no console.logs are being displayed when within the reports module.

I have read on other questions that this may have something to do with the HTTPClientModule. This HttpClientModule is only ever once initialized in my main app.module.

How do I get an interceptor to work only for a lazy loaded feature module?

auth.interceptor.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/observable';
import 'rxjs/add/operator/do';

import { AuthService } from './../services/auth/auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private auth: AuthService) {
        console.log('start interceptor');
     }

    intercept(req: HttpRequest<any>, next: HttpHandler) {

        console.log('intercepting');

        const authToken = this.auth.getProfileToken();

        console.log(authToken);

        const authReq = req.clone({
            headers: req.headers.set('Authorization', authToken)
        });

        return next.handle(authReq);

    }

}

reports.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UpperCasePipe } from '@angular/common';
import { DatePipe } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { ReportsRoutingModule } from './reports-routing.module';

...

import { SharedModule } from './../shared/shared.module';

..

import { AuthInterceptor } from './../core/interceptors/auth.interceptor';

@NgModule({
    imports: [
        CommonModule,
        SharedModule,
        ReportsRoutingModule,
    ],
    declarations: [
        ...
    ],
    entryComponents: [
        ...
    ],
    providers: [DatePipe, UpperCasePipe,
        { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
    ]
})
export class ReportsModule { }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core/core.module';
import { HttpClientModule } from '@angular/common/http';
   
@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        BrowserAnimationsModule,
        HttpClientModule,
        SharedModule,
        CoreModule.forRoot(),
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from '../app/core/guard/auth/auth.guard';

const routes: Routes = [
    {
        path: 'reports',
        loadChildren: './reports/reports.module#ReportsModule',
        canActivate: [
            AuthGuard
        ]
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
    providers: [AuthGuard]
})
export class AppRoutingModule { }

Upvotes: 27

Views: 15469

Answers (3)

hohnzy
hohnzy

Reputation: 73

Import HttpClientModule into your lazy (reports.module.ts) loaded module, then the interceptor will trigger:

...
@NgModule({
    imports: [
        CommonModule,
        SharedModule,
        ReportsRoutingModule,
        HttpClientModule,
    ],
...

Upvotes: -4

Sumit Zamadar
Sumit Zamadar

Reputation: 328

The HTTP_INTERCEPTORS provider token is reset when a lazy loaded module imports another module which imports the HttpClientModule by itself.

So HttpClientModule can be included in your application module, and is only necessary once.

https://angular.io/guide/http#setup-installing-the-module

Upvotes: 28

Praveen
Praveen

Reputation: 457

Every time a module loads in lazy loaded module a new instance of the HttpClient service is injected in the module that has not been configured to use the interceptor configured in the AppModule. So add interceptors at module level instead of application level.

Upvotes: 6

Related Questions