How to create HttpInterceptors across modules?
Asked Answered
A

1

7

I'm curious about the usage note at the bottom of the Angular docs on HttpInterceptors, it states:

To use the same instance of HttpInterceptors for the entire app, import the HttpClientModule only in your AppModule, and add the interceptors to the root application injector . If you import HttpClientModule multiple times across different modules (for example, in lazy loading modules), each import creates a new copy of the HttpClientModule, which overwrites the interceptors provided in the root module.

I don't understand how to do this. How can I get the root application injector and add the HttpInterceptor of my lazy loaded modules to it?

It seems like How to import Angular HTTP interceptor only for Child module is also trying to answer this question but the answer there is equally unclear to me.

Why does this not work, and how to properly add the second lazy loaded interceptor?

AppModule

@NgModule({
  imports: [RouterModule.forRoot(routes)], // routes contains a lazy load module
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptorService,
      multi: true,
    }
  ]
})
export class AppModule { }

Lazy loaded child module

@NgModule({
  imports: [
    LazyRoutingModule
  ],
  declarations: [ChildComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CacheInterceptorService,
      multi: true,
    }
  ]
})
export class LazyModule { }
After answered 25/10, 2019 at 22:31 Comment(6)
Why the downvotes? I researched the topic, provide my best effort towards a working solution and ask a specific and clear question.After
Your original question was : "Would something like this work?". This shows a lack of research, since the easy way to answer the question is to test it. I've retracetd my down vote, since you've apparently ended up testing it. That said, the answer is in the question: add the interceptors to the root application injectorFetid
I can see how you'd conclude that, my question might've been too stream of consciousnessy. But it's exactly that sequence of words that I don't understand. Do you mean that the only solution is to provide all the interceptors in AppModule? Doesn't this eager load the interceptor and all it's dependencies, possibly eager loading the entire lazy loaded module?After
Well, you'd try to have as few dependencies as possible. That said, AFAIK, you can also reimport HttpClientModule in your lazy loaded module: just be aware that it won't have the interceptors defined for the HttpClient defined in the root module.Fetid
@RobinDeSchepper did you find any solution? And can you give me with an example?Patrol
I think I just went with providedIn: 'root', I read somewhere that Angular automatically lazy loads them that way.After
F
1

Good morning,

Please excuse my English but I am translating this with google translator.

I am developing an application with several lazy modules and I have just developed an HttpInterceptor and I have had no problems, the process I have done has been as follows:

HttpInterceptor:

import { Injectable } from '@angular/core';
import {
    HttpInterceptor,
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpErrorResponse
} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { NotifierService } from 'angular-notifier';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {

    constructor(private notifier: NotifierService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            retry(1),
            catchError((error: HttpErrorResponse) => {
                this.notifier.notify('error', error && error.message ? error.message : 'Error');
                return throwError(error);
            }
            ));
    }
}

And to simply import into providers of app.module add:

{
       provide: HTTP_INTERCEPTORS,
       useClass: HttpErrorInterceptor,
       multi: true
}

The problem that I think you have is that when you also instantiate in the child you make a new instance which gives problems. I have read several post before doing it which indicated that it should not work but it does haha.

Just in case it is something from some new version of angular, I put the data of the project I am working on:

Angular CLI: 8.3.25 Node: 13.3.0 Angular: 8.2.14

Forsta answered 14/5, 2020 at 9:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.