Search code examples
javascriptangulartypescriptdependency-injectionangular-directive

Angular: how to inject multiple instance of abstract service


I am a bit new to Angular and trying to understand code written by a senior dev. pardon me if I do not follow with the standard communication practice and words.

I have an abstract class abstractDatService with an abstract method getEntities() which have the implementation classes as impl1 and impl2

Implementation class looks like :

@Injectable()
export class impl1 extends abstractDatService{
  
  private entities: Modal[] = [
    {
      id: 1,
      type: "a",
      name: "a1"
    },
    {
      id: 2,
      type: "a",
      name: "a2"
    }
  ];

  public getEntities(): Observable<Modal[]> {
    return of(this.entities);
  }
}

Now, in my module, I am trying to inject the service as :

  providers: [
    {
      provide: abstractDatService,
      useClass: impl1
    },
    {
      provide: abstractDatService,
      useClass: impl2
    }
  ]

In this case, when I try to get the entities they return me the entities from impl2 class only and not of impl1

I want the implementation to return both.

Can anyone help me figure out this?

EDIT :

To elaborate

I have the component where I am displaying the data in a way that

HEAD1
Data from impl1 // this line is a common component in which there is a ngFor on observable returned.

HEAD2
Data from impl2 // this line is a common component in which there is a ngFor on observable returned.

The common component is the one that displays Data from impl1 and Data from impl2 Both


Solution

  • As per the comments

    Please elaborate. what do you mean with you want them both? Do you mean you want the injected service to be a combination of both, so that getEntities returns the elements from both?

    Yes I want to inject in a way that I get data for both models impl1 and impl2

    You need to change 2 things.

    1st: Your provider definition to include multi: true

    providers: [
        {
          provide: AbstractionService,
          useClass: Impl1Service,
          multi: true,
        },
        {
          provide: AbstractionService,
          useClass: Impl2Service,
          multi: true,
        }
      ]
    

    2nd: Handle the multi Injection with array

     constructor(@Inject(AbstractionService) impls: AbstractionService[]) {
        const obs$ = impls.map(impl => impl.getEntities());
    
        combineLatest(obs$).subscribe(console.log);
      }
    

    Check the same on stackblitz: https://stackblitz.com/edit/angular-ivy-pwysue?file=src/app/app.module.ts