0

Introduction of my app structure: I have a lists-service that handles lists from API, standardized to columns and rows. It includes mapping, sorting, pagination and other functionality.

For each API, I have created child service (that extends ListsService), for example for list of users - UsersListService, actions - ActionsListService and so on.

These child services have their own data and some extra functions, specific to each.

These services are provided in the root, because in addition to being injected into each page component, they are also injected into sidebar components.

More specifically: I have LicenseListService:

@Injectable({
  providedIn: 'root'
})
export class LicenseListService extends ListsService {....}

It's injected into UserLicenseComponent (route component)

  constructor(...
    public licenseList: LicenseListService,
... ) {...}

But also in LicenseSidebarComponent, which is used in different place.

What I need

I need 2 instances of this LicenseListService, they would use the same input data (from same API), but in one I will have active licenses and in the other expired licences (so that both tables can be displayed at the same time.

One way to do it is to create child services from LicenseListService, but I would rather have 2 instances of the same service, but with status parameter (status = 'active' or status = 'expired').

What is the best way to do it?

I've seen some partial solutions (to my issue) on stackoverflow, but need to combine it into full solution.

2
  • did you try to create new injection token for new instance in your module? Commented Aug 7, 2022 at 14:16
  • like this? stackoverflow.com/a/63169683/1351452 Can I do both in same component? Or should I create child components? Commented Aug 7, 2022 at 14:38

1 Answer 1

2

you can use it in same component:

in app module:

providers: [
    { provide: 'instance1', useClass: DataService },
    { provide: 'instance2', useClass: DataService },
  ]

in your component:

constructor(
    @Inject('instance1') private service1: DataService,
    @Inject('instance2') private service2: DataService
  ) {}

Update:

if you want to initialize your services with some data you have to use custom providers:

in app module:

export function instance1Provider(): DataService {
  const dataService1 = new DataService();
  dataService1.status = 'status1';
  return dataService1;
}
export function instance2Provider(): DataService {
  const dataService2 = new DataService();
  dataService2.status = 'status2';
  return dataService2;
}

export const instance1 = new InjectionToken<DataService>('instance1');
export const instance2 = new InjectionToken<DataService>('instance2');

providers: [
    { provide: instance1, useFactory: instance1Provider },
    { provide: instance2, useFactory: instance2Provider },
  ],

in your component:

constructor(
    @Inject(instance1) private service1: DataService,
    @Inject(instance2) private service2: DataService
  ) {}

this is an example in stackblitz.

Sign up to request clarification or add additional context in comments.

4 Comments

This is good, but how I will inject some 2 different values to each of the instances. For example, instance1: status = 'status'1; instance2: status='status2'?
you mean this.service1.status=status1?
This will work as well. I was wondering if I can set some service property per instance - in providers array code.
you have to write costom providers. i updated my answer for your problem

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.