What's the Best Way to Inject One Service into Another in Angular 2 (Beta)

How to inject a provider in Angular 2 service from action?

In your action you can inject the Http in constructor and pass it into the service instance. Something like

export default class SampleAction {
private _projectService;
constructor(@Inject(Http) http: Http) {
this._sampleService = new SampleService(http);
}
}

Inject provider into another provider

In fact, injectors can be only configured at the component level or when bootstrapping the application.

When you set providers at the component level, every classes involved in the processing will have a access to these providers: sub components, services. But you can't configure providers for services themselves.

If you configure providers at the bootstrap level (when calling the bootstrap function), all elements in the application will be able to use these providers.

In fact, dependency injector of Angular2 leverages hierarchical injectors. This means that if the provider isn't found at a level, it will be look for in the level above and so on.

Here is an overview of all these elements and there relations:

Application
(providers defined in bootstrap)
|
AppComponent
(providers defined in the providers attribute)
|
ChildComponent
(providers defined in the providers attribute)
getData() --- Service1 --- Service2

To be able to use Service2 in Service1, the corresponding provider must be found in the providers tree.

In such application, we have three injectors:

  • The application injector that can be configured using the second parameter of the bootstrap function
  • The AppComponent injector that can be configured using the providers attribute of this component. It can "see" elements defined in the application injector. This means if a provider isn't found in this provider, it will be automatically look for into this parent injector. If not found in the latter, a "provider not found" error will be thrown.
  • The ChildComponent injector that will follow the same rules than the AppComponent one. To inject elements involved in the injection chain executed forr the component, providers will be looked for first in this injector, then in the AppComponent one and finally in the application one.

This answer could give you more details about the hierarchical injectors:

  • What's the best way to inject one service into another in angular 2 (Beta)?

How to share same instance of domain model in Angular2, and propagate changes?

For this you need to add your Shell service when bootstrapping your application:

bootstrap(AppComponent, [ Shell ]);

And remove it from all viewProviders attribute of your components:

@Component({
selector: 'my-app',
providers: [TemplateRef],
templateUrl: './angular/app/Index.html',
directives: [ROUTER_DIRECTIVES, NgIf],
// viewProviders: [Shell] <-------
})

It's because of the way the "hierarchical injectors" feature of Angular2 works. For more details you could have a look at this question:

  • What's the best way to inject one service into another in angular 2 (Beta)?

How to inject new instance of same component in Angular2

Angular2 doesn't allow to bootstrap the same component twice in an HTML page.

This is however possible to bootstrap different application components if you want in a same HTML page.

See this documentation for more details:

  • https://angular.io/docs/ts/latest/api/platform/browser/bootstrap-function.html (Section "Bootstrapping Multiple Applications")

Edit

Regarding your second question, you need to be aware that @Component and @Injectable are decorators. They are responsible to "wrap" target instances and allow dependency injections by providing right dependency instances in constructor based on configured metadata.

Regarding hierarchical injectors, you could have a look at this link:

  • What's the best way to inject one service into another in angular 2 (Beta)?

Angular2 - Share data between components using services

You define it within your two components. So the service isn't shared. You have one instance for the AppComponent component and another one for the Grid component.

@Component({
selector: 'my-app',
templateUrl: 'app/templates/app.html',
directives: [Grid],
providers: [ConfigService]
})
export class AppComponent {
(...)
}

The quick solution is to remove the providers attribute to your Grid component... This way the service instance will be shared by the AppComponent and its children components.

The other solution is to register the corresponding provider within the bootstrap function. In this case, the instance will be shared by the whole application.

bootstrap(AppComponent, [ ConfigService ]);

To understand why you need to do that, you need to be aware of the "hierarchical injectors" feature of Angular2. Following links could be useful:

  • What's the best way to inject one service into another in angular 2 (Beta)?
  • https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

How can I call a service provider within another one - angularjs2

Just define this service when bootstrapping your application and inject it in the service you want to use it:

bootstrap(AppComponent, [ CardService , ProductService ]);

In the service:

@Injectable()
export class CardService {
constructor(private _productService: ProductService) {
}
}

Don't forget to specify the @Injectable decorator.

This question could give more details on how dependency injection, hierarchical injectors and injection into services work:

  • What's the best way to inject one service into another in angular 2 (Beta)?

Angular 2 Component Interaction via a service

If you add the "shared" service to providers of each component

@Component({
selector: 'dir2',
template: '{{field}}',
providers: [DirService]
})

then for each component a new instance is maintained.

To get a shared service you either add it only in bootstrap(AppComponent, [DirService]) or one common ancestor of the components and directives that defines the root component and the scope of the shared service.

This way every descendant gets the same instance.

Plunker example

See also

- AngularJs 2 - multiple instance of service created

- How to use Dependency Injection (DI) correctly in Angular2?



Related Topics



Leave a reply



Submit