3

I'm following the angular docs for Dependency Injection and tried to duplication the section on dependency injection tokens. But it's clear I still don't get it.

I'm trying to use a value provider to inject an config:any into my project.

At the simplest level, I just want to provide a const string

// app-modules.ts
const CFG_STRING = "I was declared externally and injected in ngModule"    
@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  providers: [
    {provide: CFG_STRING, useValue: CFG_STRING}
  ],
  bootstrap: [ App ]
})

and inject into a Component constructor

// app.ts
const LOCAL_STRING = "I was declared in the local module"
export class App {
  constructor(
    // @Optional() cfgString: CFG_STRING
  ) {
    this.name = 'Angular2'
    this.local = LOCAL_STRING

    /* provided/injected */
    // this.injectedStr = cfgString
  }
}

But when I do so the app doesn't run correctly. What am I doing wrong?

Here's a plunkr: http://plnkr.co/edit/sQwxyDqLkMTgVUjJ1yYF?p=preview

michael
  • 4,377
  • 8
  • 47
  • 73

1 Answers1

1

If you don't use a type as key for the provider but instead a string or OpaqueToken you need to pass the key to @Inject()

constructor(
    @Inject('CFG_STRING') /* @Optional()*/ cfgString: CFG_STRING
  ) {

and provide it like

  providers: [
    {provide: 'CFG_STRING', useValue: CFG_STRING}
  ],

CFG_STRING is not a type and can therefore not be used as key. Either you use some string or mentioned an OpaqueToken. It can be any string, it just needs to match between provide and @Inject()

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • This is so awesome. why do I waste so many hours trying to RTFM when I can just ask on stackoverflow?!?? BTW, the angular.io cheatsheet does not pass the key as a string, https://angular.io/docs/ts/latest/guide/cheatsheet.html – michael Sep 06 '16 at 09:12
  • If you use a type, then you don't need to, but `CFG_STRING` is not a type, it's a string constant. `MyValue` in `{ provide: MyValue, useValue: 41 }` has to be a type though. – Günter Zöchbauer Sep 06 '16 at 09:18
  • what kind of Type would MyValue be to accept a number as the `useValue`? `let MyValue: number` did not work – michael Sep 06 '16 at 09:23
  • The constructor parameter would need to be `number` but you can then use `constructor(@Inject(MyValue) private myValue:number)` – Günter Zöchbauer Sep 06 '16 at 09:25
  • 1
    I mean, what is an example of `MyValue` in ` { provide: MyValue, useValue: 41 }` where `MyValue` is a Type and can accept a number as an assignment? – michael Sep 06 '16 at 09:30
  • I don't think there is another type than `number` where you can assign `41` to, but maybe there are some TS tricks that allow you to do that. I don't have deep TS knowledge. I use only Dart with Angular2. – Günter Zöchbauer Sep 06 '16 at 09:33