patrick
patrick

Reputation: 9752

how do I set a config object as a dependency injectable?

Say I have a interface like:

interface MyConfig {
  sort: true,
  onClick: () => void,
  // ... other props
}

and then I have a directive/component which utilizes several internal services. So, for example I might have two or three instances of this directive on a given page, which would each have their own unique config...

My question is, how do I make it so that the internal services can have access to their respective config via dependency injection? In other words, I would like to have my services structured like:

export class InternalServiceA {
  constructor (config: MyConfig) {}
}
...
export class InternalServiceB {
  constructor (config: MyConfig) {}
}

So that each rendered directive instance, would have it's own group of internal services with their own config.

...

I am currently working on a service, and in my spec I was doing:

providers: [ { provide: MyConfig, useValue: { name: 'my-config' } } ]

and I am getting:

'MyConfig' only refers to a type, but is being used as a value here.

Also, a side question, what would be the best way to expose one of these internal dependencies to other components? Like for example, one of these services will be responsible for fetching data from api endpoints, and so I may have a totally isolated component that needs to know something about the response from that endpoint (say like a total count or something). What would be the best way to make that data available to things outside of the directive that "owns" the services?

Upvotes: 0

Views: 263

Answers (1)

Fatih Ersoy
Fatih Ersoy

Reputation: 739

You have to inject the dependency with a decorator. You should whether inject MyConfig type, or the object you created ({ name: 'my-config' }). Either do;

import { InjectionToken } from '@angular/core';

export const MY_CONFIG = new InjectionToken<{name:string}>('my.config');

providers: [ { provide: MyConfig, useValue: { name: 'my-config' } } ]

export class InternalServiceA {
  constructor (@Inject(MY_CONFIG) config: {name:string}) {}
}

or do;

import { InjectionToken } from '@angular/core';

export const MY_CONFIG = new InjectionToken<MyConfig>('my.config');

providers: [ { provide: MY_CONFIG, useClass: MyConfig } ]

export class InternalServiceA {
  constructor (@Inject(MY_CONFIG) config: MyConfig) {}
}

To use useValue you need to initialize. It must be an instance of a class, object, array etc. If you want to inject a definition you need to use useClass.

edit: for further information please read the documentation.

Upvotes: 1

Related Questions