How do I inject httpClient into an instantiated service?
Asked Answered
S

2

6

I am instantiating MyService in app.module.ts, and providing it throughout my code.

However, I want MyService to use httpClient, and I am unable to angular-idiomatically instantiate httpClient to pass as a parameter to MyService. I'm not sure what the right way to access httpClient in MyService is.

I've looked at instantiating httpClient directly and then passing it as a parameter to my service. However it seems this creates a circular dependency. I have also tried messing with Injectors but this is specifically advised against by the Angular team apparently. I strongly feel I am missing something simple.

app.module.ts

imports: [
    ...
    httpClientModule
    ...
],

function MainServiceFactory() {
    return new MyService();
}
...
providers: [{
    provide: MyService,
    useFactory: MainServiceFactory
}],
...

MyService.ts

...
constructor(private http : HttpClient) {
    ...
}

Without instantiation and passing as parameter of httpClient: I get an "error in app.module.ts, expected 1 argument", naturally! With instantiation I break angular recommendations.

Edit: I had neglected to specify that I did import the httpClientModule

Strapless answered 11/1, 2019 at 22:9 Comment(3)
Have you considered just including the HttpClientModule? Your service factory doesn't actually match the constructor signature of the service, so there's no rational basis to expect that it might work.Belford
See the first section of the HttpClient Documentation - Setup => Before you can use the HttpClient, you need to import the Angular HttpClientModule. Most apps do so in the root AppModule.....Roxana
Once you do that then learn how to register your service type with angular. There is no reason to create a custom factory in this case. If you were to follow along with the tutorial or documentation on angular.io this would be one of the things covered early on.Roxana
L
3

As everyone say, you have to import HttpClientModule

Looking to your code, I think you are trying to deal with angular's dependency injection:

I did an example in the stackblitz:

https://stackblitz.com/edit/angular-yqvlv7?file=src%2Fapp%2Fapp.module.ts

Where I define an abstract class to behave like an interface, and then my.service implements this interface.

Inside the app.module, I provide the 'interface' using my-service class. After all this, you can inject the 'interface' in the component (in this link, hello.component.ts)

The HttpClient is injected only in my-service and there is no problem at all.

I hope it helps you to understand it better.

Lassie answered 11/1, 2019 at 22:52 Comment(1)
It doesn't work for Angular 12. I am geting NullInjectorError: No provider for MyService.Decastyle
E
1

As stated in the Angular API the FactoryProvider has an optional deps field inherited from core/FactorySansProvider. This field is an array where you can put dependencies for your factory. The only needed changes are:

function MainServiceFactory(http: HttpClient) {
    return new MyService(http);
}

providers: [{
    provide: MyService,
    useFactory: MainServiceFactory,
    deps: [HttpClient]
}],

Here a reference to Angular dependency providers. The documentation also says that the useFactory should be used to evaluate run time dependencies and not static ones, but I guess that you have multiple options in your real code.

Entrain answered 8/2, 2022 at 13:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.