Reputation: 92440
I have a typescript class representing a model and I would like instances to communicate with an API via angular's Http
service.
But the constructor of the model needs arguments when creating instances. For example something super simple:
class SomeModel{
constructor(public id:number, public name:string, ){
}
I would like to inject the Http
service so it is available to my instances, but it seems like the canonical way to do this commandeers the constructor with:
constructor(http:Http)
I've been digging through the Injector
docs, but it's a little sparse and I haven't found anything that works. Is there a way to get a reference to a service like Http
from the DI system without using the constructor pattern?
Upvotes: 13
Views: 8437
Reputation: 6287
I managed to solve the same problem using angular 4. First you create new injector that uses component injector. It knows about your SomeModel
class and passes modelParams
as instance of SomeModelParameters
class. Then you use this newly created injector to create class instance.
@Injectable()
class SomeModel {
constructor(http: Http, someModelParamters: SomeModelParameters) { }
}
export class MyComponent {
constructor(injector: Injector) {
const modelParams = new SomeModelParameters();
const injectorWithModelParams = ReflectiveInjector.resolveAndCreate(
[
SomeModel,
{ provide: SomeModelParameters, useValue: modelParams }
],
injector);
this.someModel = injectorWithModelParams.resolveAndInstantiate([SomeModel]);
}
}
Upvotes: 4
Reputation: 657228
update
HTTP_PROVIDERS
is long gone.
HttpClientModule
is the current replacement.
original
If you inject a class that has constructor parameters the @Injectable
annotation needs to be added.
@Injectable()
class SomeModel{
// constructor(public id:number, public name:string, ){
// }
constructor(http:Http) {}
}
For this to work HTTP_PROVIDERS
needs to be added to bootstrap(AppComponent, [HTTP_PROVIDERS]);
See also Angular2 beta - bootstrapping HTTP_PROVIDERS - "Unexpected Token <"
If you need to pass other arguments from your component, youcoud pass them using a function instead.
Another way is to create the instance manually and request Http
from the injector.
export class MyComponent {
constructor(injector: Injector) {
this.someModel = new SomeModel(Injector.resolveAndCreate(Http), 1, 2);
}
}
Upvotes: 2