Mark
Mark

Reputation: 92440

Dependency injection in Angular 2 when a constructor has arguments

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

Answers (2)

Stanislav Berkov
Stanislav Berkov

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

Günter Zöchbauer
Günter Zöchbauer

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

Related Questions