Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting Service Providers in Angular 2.0

In the AngularJS 2.0 Heroes tutorial explanation it states that if a child component includes a service in its @Component Providers list, then Angular will create a separate instance of that service specific to the child. What I don't understand is what you would do if sometimes you wanted to use the child component independently, and other times within a parent component. This seems like a severe restriction. I've just playing with Angular 2.0, so most likely I've misunderstood something.

Here's the explanation from the Angular.io site from the Services section of the Heroes Tutorial.

Appendix: Shadowing the parent's service

We stated earlier that if we injected the parent AppComponent HeroService into the HeroDetailComponent, we must not add a providers array to the HeroDetailComponent metadata.

Why? Because that tells Angular to create a new instance of the HeroService at the HeroDetailComponent level. The HeroDetailComponent doesn't want its own service instance; it wants its parent's service instance. Adding the providers array creates a new service instance that shadows the parent instance.

Think carefully about where and when to register a provider. Understand the scope of that registration. Be careful not to create a new service instance at the wrong level.

Here's the link to the page this came from to put it in context.

like image 470
Darryl Avatar asked Jan 25 '16 01:01

Darryl


People also ask

Can you inject a service into a service Angular?

Angular provides the ability for you to inject a service into a component to give that component access to the service. The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency.

What are injectors and providers in Angular?

An Angular injector is responsible for creating service instances and injecting them into classes. Usually injectors work behind the scenes. Below code shows injector being explicitly created. constructor(private injector: Injector) { } The below code inject the service directly to the host component.

What's the best way to inject one service into another in Angular?

Use the @Injectable() decorator on any service that depends on another. Inject the other services into the constructor of the dependent service.

What are providers in angular 2?

A provider is an instruction to the Dependency Injection system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide. For the final sample application using the provider that this page describes, see the live example / download example .


1 Answers

If you want a Component to have its own instance of a Service and at the same time to have an instance of its parent's service you have to take a look at @SkipSelf()

Consider the following code

class Service {
    someProp = 'Default value';
}

@Component({
  providers : [Service] // Child's instance
})
class Child {
  constructor(
    @SkipSelf() parentSvc: Service, 
    svc: Service
    ) {
        console.log(pSvc.someProp); // Prints 'Parents instance'
        console.log(svc.someProp);  // Prints 'Default value'
    }
}

@Component({
  providers : [Service] // Parent's instance
})
class Parent {
  constructor(svc: Service) {
    svc.someProp = 'Parent instance';
  }
}

With @SkipSelf() we are telling the component to start the dependency resolution from the parent injector (the name SkipSelf says a lot, I guess).

You can read more about visibility in Host and Visibility in Angular 2's Dependency Injection from @PascalPrecht.

Check this plnkr with a working example.

like image 75
Eric Martinez Avatar answered Nov 06 '22 17:11

Eric Martinez