Angular 2 OpaqueToken

Need help providing an OpaqueToken. Using Angular 2 beta-12. It works fine if the provider key is a string, but does not work when using OpaqueToken. In the Child SF class, it is undefined.

Parent class:

export let SF = new OpaqueToken('sf'); export class A { testMsg: string = 'hello'; } @Component({ template: `<child></child>`, providers: [ provide(SF, {useValue: A}), provide('justString', {useValue: 'hi'}) ] }) export class App {} 

Child class:

 import {Component, Injector, Inject, OpaqueToken} from 'angular2/core' import {SF, A} from './app' console.log("******", SF); // undefined @Component({ selector: 'child', template: ` $$CHILD Rendered$$ {{a}} ` }) export class Child { //constructor(@Inject(SF) private a: A) {} // doesn't work constructor(@Inject('justString') private a: string) {} } 

Exceptions:

angular2.min.js: 17EXCEPTION: cannot resolve all parameters for "Child" (@Inject (undefined)). Make sure that all parameters are decorated with Inject or have valid type annotations, and that "Child" is decorated with Injectable.

+6
source share
3 answers

This is because you have a circular dependency between modules that contain the parent and child classes.

If you define your opaque token in the third module and include it in others, it will work.

For example, a permanent module:

 export let SF = new OpaqueToken('sf'); 

And in two other modules:

 import { SF } from './constants'; 
+9
source

Use InjectionToken replace with OpaqueToken in angular 4 or later.

Because OpaqueToken is deprecated

fooobar.com/questions/314595 / ...

+2
source

I assume that your parent and child classes are in different files and that you import Child into the parent file so that you can put it in the directives Parent decorator (you don’t have to do this in your example, but otherwise the Child will not be created at all , which is clearly not the case).

In this case, you need to use forwardRef everything that is defined in the file of the parent class, which is used in the file of child classes, which should be loaded first, because it is imported into the parent class and, therefore, is not tied to anything defined later uploaded file (no workaround which forwardRef )

So,

 import {forwardRef} from "angular2/core"; ... constructor(@Inject(forwardRef(()=>SF)) private a: A) {} 

should work where

 constructor(@Inject(SF) private a: A) {} // doesn't work 

fails.

Sidenote: provide(SF, {useValue: A}) , where A is a reference to a class, not an instance, the smell is fishy. I will not reflect on what you are doing, but I will say that it is much more typical to see that useValue used with reference to the instance and useClass used with reference to the class.

+1
source

All Articles