Picci
Picci

Reputation: 17752

Angular2 - Use Dependency Injection outside Components

In my app I use DI to pass information about the UserLogged around the different Components that need such info. This means that I have a main.ts class like this

import {AppComponent} from './app.component';
import {UserLogged} from './userLogged'

bootstrap(AppComponent, [UserLogged]);

and the components that need to use the instance of UserLogged have a constructor like this

constructor(private _user: UserLogged)

Now I would like to use the same instance of UserLogged also in simple TypeScript classes (which are not @Component). Is this possible? In other words, can I get hold of the same instance of UserLogged injected by DI also if I am outside a @Component?

Upvotes: 4

Views: 4496

Answers (4)

Timothy Zorn
Timothy Zorn

Reputation: 3231

In the file where you bootstrap angular:

import { AppComponent } from './app.component';
import { UserLogged } from './userLogged';

declare global {
    var injector: Injector;
}

bootstrap(AppComponent, [UserLogged]).then((appRef) => {
    injector = appRef.injector;
});

In your other file:

import { UserLogged } from '../path/to/userLogged';

class TestClass {
    private userLogged: UserLogged;

    constructor() {
        this.userLogged = injector.get(UserLogged);
    }
}

Upvotes: 2

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

Reputation: 657118

This constructor also works for services (other classes created by DI)

 bootstrap(AppComponent, [OtherClass, UserLoggged]);

 @Injectable()
 export class UserLogged {
   log(text) {
     console.log(text);
   }
 }

 @Injectable()
 export class OtherClass {
   constructor(private _user: UserLogged) {}
 }

 class SomeComponent {
   constructor(private otherClass:OtherClass) {
     this.otherClass._user.log('xxx');
   }
 }

If you create these classes using new SomeClass() then you can inject it like

 class SomeComponent {
   constructor(private _injector:Injector) {
     let userLog = this._injector.get(UserLogged);
     new SomeClass(userLog);
   }
 }

Upvotes: 3

Pratik Kelwalkar
Pratik Kelwalkar

Reputation: 1632

Im taking a wild guess here, but do you mean to say you want to Inject the class with having to use providers : [UserLogged] ? If that is the case, this will work

providers: [ provide(UserLogged, {useClass: UserLogged} ] 

add the above to your bootstrap and you are good to go when you 'do not want to use @Component'

sample.ts

export class Sample{
   constructor(private ulog : UserLogged){}
}

In your case the bootstrap would be :

import {provide}   from   'angular2/core';
import {HTTP_PROVIDERS}   from  'angular2/http';
bootstrap(AppComponent,[HTTP_PROVIDERS,provide(UserLogged, { useClass : UserLogged})]);

Ive added the HTTP_PROVIDERS to demonstrate how to add multiple providers. Cheers!

Upvotes: 0

Thierry Templier
Thierry Templier

Reputation: 202148

To be able to use dependency injection in classes you need to have a decorator, the @Injectable one.

@Injectable()
export class SomeClass {
  constructor(private dep:SomeDependency) {
  }
}

The name Injectable isn't really self-explanatory. It's to make possible the injection within the class (and not into another class).

The provider for the SomeDependency class need to be visible from the component that initiates the call.

See this question for more details about dependency injection and hierarchical injectors:

Upvotes: 0

Related Questions