question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

Extend http interceptors in child module injector

See original GitHub issue

šŸš€ feature request

Relevant Package

This feature request is for @angular/common/http

Description

Ability to extend http interceptors in child module injectors since it is fairly simple, but the api to achieve it is ā€œprivateā€ in angular.

Describe the solution youā€™d like

Iā€™ve already managed to do this by providing HttpHandler, HttpClient and HTTP_INTERCEPTORS manually in the lazy loaded module without importing HttpClientModule, since this module imports HttpClientXsrfModule which provides a fresh HTTP_INTERCEPTORS array, for the sake of reincluding HttpXsrfInterceptor (imho, but why again?).

If this explanation was hard to follow, hereā€™s the code

@NgModule({
	providers: [{
		provide: HttpClient,
		useClass: HttpClient
	}, {
		provide: HttpHandler,
		useClass: ɵHttpInterceptingHandler
	}, {
		provide: HTTP_INTERCEPTORS,
		deps: [Injector],
		useFactory: injector => [
			...ARRAY_OF_CHILDREN_INTERCEPTOR,
			...injector.parent.get(HTTP_INTERCEPTORS)
		]
	}]
})
export class FeatureModule {}

Here the ā€œprivateā€ angular api is the class ɵHttpInterceptingHandler and the injector.parent part.

So, I think the most practical solution would be to maybe have an alternative HttpClientModule that does not import HttpClientXsrfModule so the interceptors array is not reset.

Or similarly, have both these modules without providers and have .forRoot(): ModuleWithProviders options for each, of which HttpClientModule.forRoot() would spread HttpClientXsrfModule.forRoot()'s providers.

Code again, if explanation was convoluted

class HttpClientModule {
	static forRoot(): ModuleWithProviders<HttpClientModule> {
		return {
			ngModule: HttpClientModule,
			providers: [
				// taken from source code as of version 9
				HttpClient,
				{provide: HttpHandler, useClass: HttpInterceptingHandler},
				HttpXhrBackend,
				{provide: HttpBackend, useExisting: HttpXhrBackend},
				BrowserXhr,
				{provide: XhrFactory, useExisting: BrowserXhr},

				// HttpClientXsrfModule providers
				...HttpClientXsrfModule.forRoot().providers
			]
		}
	}
}

Describe alternatives youā€™ve considered

Other, perhaps more suitable or powerful solutions, are definitely more difficult to implement.

One might be to extend capabilities of multi interceptors (or add another multi special type) to be able to extend themselves with the array of the parent injector.

Lastly, in another train of thought, this problem may delve a little into the ā€œproblemā€ that ModuleWithProviders doesnā€™t solve thoroughly, being that provider inclusion is not completely controlled if the module in question imports another module that provides something. And even if the second module has a static ModuleWithProviders method for the same argument, you canā€™t (not in a conventional manner) control which module version to import from within these methods.

i.e. ModuleWithProviders canā€™t solve providers in deeper module imports with its intended design. Hence, the most complicated solution would be to redesign this.

These are a lot less practical solutions, but since thereā€™s the section, I might as well mention them.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:37
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

11reactions
miguel-leoncommented, Mar 6, 2021

Hello, itā€™s been a while since I opened this issue as a feature request. Iā€™ve seen some interactions, among them, HttpHandler level proposed implementation, and even calling it a bug (https://github.com/angular/angular/issues/39125). I wanted to say, I still see this as a framework design decision motivated by conceivable use cases. In that reasoning, I wrote an article commenting on some possibilities regarding that. Even uploaded a working example to github. So, youā€™re welcome to read. https://miguel-leon.medium.com/extending-http-interceptors-hierarchically-in-angular-4ca4d25af475

Cheers!

5reactions
miguel-leoncommented, May 29, 2020

Hi, thanks for the comment!

I realize now that I didnā€™t specify whether I meant ā€œextending interceptorsā€ as in enlarging the main set of interceptors or as in having different sets of interceptors. I guess modifying the provider in my example a little would allow both cases.

But actually I meant neither (and both?). What I meant was for children module (lazy loaded) injectors to have its own set of interceptors but also benefit from the main ones (a hierarchy).

This was actually the use case in my project. I wanted my child module to apply the application wide interceptors, but also its own ā€œprivateā€ set of interceptors. And in retrospective, I donā€™t know if it would have been all OK if this child module would have updated the main set of interceptors. Also the child module was a library (yes, a lazy loaded module in a library with Ivy).

In summary, I think both your set of rules and my use case can be achieved. But I wouldnā€™t want to see this feature restricted to only one way. I rather it to not change.

In any case, both ways have the same (lack of) difficulty to implement, and IMHO, I donā€™t see only one set of interceptors as a superior design, both designs have their pros and cons.

I hope I clarified some things. Thanks again! Regards.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Extending HTTP Interceptors Hierarchically in Angular
Say something particular only to the feature module needs to be done on every http request, but the common interceptors still need to...
Read more >
Extending HTTP Interceptors Hierarchically in Angular - Morioh
Say something particular only to the feature module needs to be done on every http request, but the common interceptors still need to...
Read more >
Angular2 Http Interceptor not working in child module
I got it working from the child module by just importing the RequestInterceptor, and setting it up in the providers for the module,...
Read more >
Angular: When HttpInterceptor doesn't work with lazy loaded ...
If you're doing Angular the right way, you should be using some kind of http interceptor. An HttpInterceptor provides a standard way toĀ ......
Read more >
How to split HTTP Interceptors between multiple backends
This article will teach you how to implement different types of the standard HttpClient version and associate module scoped interceptors with each type....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found