1

I have a situation where I want to be able to have multiple widget components used on the page at the same time. I want to isolate the ContainerComponent dependencies so that each ContainerComponent instance references unique service instances.

For example I would like every instance of the following component to have a unique instance of the "FhirService":

export class ContainerComponent implements OnInit, OnDestroy, AfterViewInit {
...
constructor(private _fhir: FhirService, private _questionnaireService: QuestionnaireService, private cdr: ChangeDetectorRef) {}

Service definition:

@Injectable({
  providedIn: 'root'
})
export class FhirService {
  public guidanceResponseBS: BehaviorSubject<GuidanceResponse>;

  constructor(private _http: HttpClient, private _settingsService: SettingsService) {
    this.guidanceResponseBS = new BehaviorSubject<GuidanceResponse>(null);
  }

...

How is this done?

cobolstinks
  • 6,801
  • 16
  • 68
  • 97
  • I suppose that you may be trying use service in a wrong way. They are initially needed to extract some logic (methods) thus you don't need more than one instance to work with these methods since they are stateless. You could make as many components as you wish and have variables inside while using the same service which would just do some logic service – Sergey Dec 04 '18 at 20:35

2 Answers2

3

If you want to provide unique service instance to diffrent component, You will have to add the service In the @Component() decorator for a component. You should add these services to providers array for child Module declarations or to component declaration:

You can configure injectors with providers at different levels of your app, by setting a metadata value in one of three places:

In the @Injectable() decorator for the service itself.

In the @NgModule() decorator for an NgModule.

In the @Component() decorator for a component.

EX:

 @Component({
  selector: 'app-hero-list',
  template: `
    <div *ngFor="let hero of heroes">
      {{hero.id}} - {{hero.name}}
    </div>
  `,
 providers: [myService]
})
nircraft
  • 8,242
  • 5
  • 30
  • 46
  • thanks this is pretty cool, just know that if you find and implement this you'll need to update your TestBed configuration in your unit tests to follow this: https://stackoverflow.com/a/39894266/491436 – cobolstinks Dec 04 '18 at 21:53
0

To begin with, you should not need to have more than one instance of a service in angular. It is a DI framework and as such you should(in most of cases) have a single instance of each service.

The thing that may lead you think that you eventually need to have a specific/separate instances of the service for each class is that with the statement:

public guidanceResponseBS: BehaviorSubject<GuidanceResponse>;

you are coupling the concept of data (state) with that of a business logic. Your services are not supposed to contain/save data, at least not the once that you intend as business logic ones.

Now, there are also services that will contain data, but that is generally done for the purpose of sharing the data among more components in the applicaiton. Generally, in these cases, you load the data at same stage and you save it in a service to make it available for future use.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
  • the DI framework in angular is specifically designed to allow multiple instances of services... there are many use cases for multiple service instances in any application and the vast majority of DI frameworks provide for it. This much is specifically stated in the angular docs. – bryan60 Dec 04 '18 at 20:34
  • It allows, but in your case is just a misuse IMO – NiVeR Dec 04 '18 at 20:39
  • @NiVeR not his :) – Sergey Dec 04 '18 at 20:41
  • He isn't the author of this question :) – Sergey Dec 04 '18 at 20:43
  • 1
    not my question, but a stateful service is a potential use case for multiple instances of a service if that state is unique to each instance of the component. This could be how a container component communicates with or shares state with child components. – bryan60 Dec 04 '18 at 20:55
  • I understand that in most cases this is bad practice to have your services be stateful, but in this particular case I can't pull in something like ngrx to store my state and need to do so in the services. – cobolstinks Dec 04 '18 at 21:00
  • @cobolstinks stateful services are NOT bad practice. It's just important to understand how and why to use them. – bryan60 Dec 04 '18 at 21:02
  • @bryan60 I guess there are such necessities. Stateful services are perfectly fine, it is just that multiple instance of stateful service makes sense only when you can modify the state client-side, and you are not applying the changes directly to the external store containing the state. – NiVeR Dec 04 '18 at 21:09