Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update dependency injection token value

Angular dependency injection let you inject a string, function, or object using a token instead of a service class.

I declare it in my module like this:

providers: [{ provide: MyValueToken, useValue: 'my title value'}]

and I use it like this:

constructor(@Inject(MyValueToken) my_value: string) {
  this.title = my_value;
}

However, how can I update the value from the component and let other components get every time the new value? in other words, I want to simulate the functionality of using something like a BehaviorSubject to emit and receive values.

If this is not possible then what is the use of those injection tokens values if they provide only static data as instead I can simply declare the static value in my component and use it directly.

like image 345
Hamed Baatour Avatar asked Oct 15 '17 12:10

Hamed Baatour


People also ask

What is dependency injection token?

The Dependency Injection system in Angular uses tokens to uniquely identify a Provider. There are three types of tokens that you can create in Angular. They are Type Token, String Token, and Injection Token. DI Tokens.

What is the default token in Angular dependency injector?

If you specify the service class as the provider token, the default behavior is for the injector to instantiate that class using the new operator. In the following example, the Logger class provides a Logger instance.

How do you use an injection token?

To register a dependency using InjectionToken , we first need to create the InjectionToken class instance: export const APP_CONFIG = new InjectionToken('Application Configuration'); Then, use the token to register the dependency: { provide: APP_CONFIG, useValue: {name:'Test App', gridSetting: {...} ...});

When should I use InjectionToken?

Use an InjectionToken whenever the type you are injecting is not reified (does not have a runtime representation) such as when injecting an interface, callable type, array or parameterized type. InjectionToken is parameterized on T which is the type of object which will be returned by the Injector .


2 Answers

Instead of a primitive which is immutable, you can use a BehaviorSubject, then access and update it in one component and subscribe in the other:

providers: [{ provide: MyValueToken, useValue: new BehaviorSubject('')}]

// consumer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.subscribe((my_value)=>this.title = my_value);
}

// producer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.next('my title value');
}
like image 109
Max Koretskyi Avatar answered Sep 22 '22 17:09

Max Koretskyi


In addition to the Wizard:

If you have a use-case where every consumer needs its own instance of BehaviourSubject. (I happen to be in this use-case). Make sure you define a factory.

const myFactory = () => { return new BehaviorSubject<string>('') };

providers: [
    { provide: MyValueToken, useFactory: myFactory }
]

// Then, as proposed in the top-answer.

// consumer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.subscribe((my_value)=>this.title = my_value);
}

// producer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.next('my title value');
}
like image 37
Andre Elrico Avatar answered Sep 20 '22 17:09

Andre Elrico