I am running into 'opaque tokens' as a solution to implementing global constants in Angular 2, for example here: Define global constants in Angular 2
Despite reading the docs, I can't seem to grasp the point.
Using an OpaqueToken is preferable to using strings as tokens because of possible collisions caused by multiple providers using the same string as two different tokens.
What? What's an Angular2 token to begin with? All I get on google are answers on JSON Web Tokens (their role in auth, etc, etc), which I understand, but are obviously not related in any way.
What's an Opaque Token? What is it used for?
P.S. More docs on opaque tokens as used to provide constants. They didn't help me very much, however.
An Opaque Token is just a runtime class that is used as a unique identifier for injector providers. Lets say you have a value, 'secretId' that you want to use into a few services and components. You don't want to hard code this in your services and components, as it will change in the future.
Opaque access tokens are tokens in a proprietary format that you cannot access and typically contain some identifier to information in a server's persistent storage. To validate an opaque token, the recipient of the token needs to call the server that issued the token.
What is an Injection Token. The Injection Token allows creating token that allows the injection of values that don't have a runtime representation. It is very similar to string tokens. But instead of using a hardcoded string, we create the Injection Token by creating a new instance of the InjectionToken class.
update Angular4
In Angular4 OpaqueToken
is deprecated and will be replaced by InjectionToken
. InjectionToken allows to pass a generic type parameter.
export let APP_CONFIG = new InjectionToken<MyConfig>("app.config");
See also
original
What? What's an Angular2 token to begin with?
What's an Opaque Token? What is it used for?
A token is a key for providers of Angulars dependency injection. Providers are registered with a key and components, directives, and service classes instantiated by DI get dependencies injected which are looked up by provider keys.
DI supports types, strings, OpaqueToken
and objects as keys.
export let APP_CONFIG = new OpaqueToken("app.config"); export let APP_CONFIG_2 = {}; providers: [ MyService, // type is key and value {provide: MyService, useClass: MyFancyServiceImpl}, // type is key, `MyFancyServiceImpl` is the value (or rather the information how to create the value {provide: 'myservice', useClass: MyService}, // key is a string {provide: APP_CONFIG, useValue: {a: 'a', b: 'b'}} // key is an `OpaqueToken` {provide: APP_CONFIG_2, useValue: {a: 'a', b: 'b'}} // key is an object ]
// one of these decorators needs to be added to make DI work @Injectable() @Component() @Directive() @Pipe() class MyComponent { // DI looks up a provider registered with the key `MyService` constructor(private myService: MyService) {} // Same as before but explicit constructor(@Inject(MyService) private myService: MyService) {} // DI looks up a provider registered with the key 'myService' constructor(@Inject('myservice') private myService: MyService) {} // DI looks up a provider registered with the `OpaqueKey` `APP_CONFIG` constructor(@Inject(APP_CONFIG) private myConfig: any) {} // DI looks up a provider registered with the object `APP_CONFIG_2` constructor(@Inject(APP_CONFIG_2) private myConfig: any) {}
The object key (APP_CONFIG_2
) and the OpaqueToken
(APP_CONFIG
) need to be the exact same instance. A different instance with the same content won't work. This makes it easy to look up where the key is declared and whether the provider and the injection target use the same key.
For a string it can be a different instance, this brings the risk, that the same string value is used in different modules and might cause conflicts or the wrong provider being injected.
What's an Opaque Token? What is it used for?
Opaque Token used for inject another provider(service) with same name.
This allows you to avoid naming collisions.
const MY_HTTP_TOKEN: OpaqueToken = new OpaqueToken('Http'); providers: [ { provide: MY_HTTP_TOKEN, useClass: Http } ] constructor(@Inject(MY_HTTP_TOKEN) private myHttpService){}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With