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 { }
In general, you want to create you interceptor as a singleton, so it can be used across your application and only instantiated once by Angular's DI. This involves for your lambda Angular app; Adding the provider definition to the providers configuration of CoreModule.
If you want to check how lazy loading works and how lazy loading routing flow, then Augury is the best tool we have. Click on ctrl+F12 to enable the debugger and click on the Augury tab. Click on the router tree. Here, it will show the route flow of our modules.
To lazy load Angular modules, use loadChildren (instead of component ) in your AppRoutingModule routes configuration as follows. content_copy const routes: Routes = [ { path: 'items', loadChildren: () => import('./items/items. module'). then(m => m.
You can lazily load a component in any other component, hence creating a parent-child relationship between them. You want to lazy load GreetComponent on the click of the button in the parent component, so to do that add a button as shown next.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With