Royalsmed
Royalsmed

Reputation: 222

Angular 5 Injector - How to inject string

I am trying to inject strings into my angular component. The code below works fine but it gives a deprecation warning: get is deprecated: from v4.0.0 use Type or InjectionToken

@Component({
  selector: 'app-label',
  templateUrl: './label.component.html',
  styleUrls: ['./label.component.scss']
})
export class LabelComponent {
  public name: string;
  public caption: string;
  constructor(
    private injector: Injector
  ) {
    this.name = this.injector.get('name');
    this.caption = this.injector.get('caption');
  }
}

So i tried to work with this very short and incomplete documentation Angular 5 Injector to come up with something like below, however I don't want to useValue or useClass, what I need is the actual value injected.

    class BS { }
    // [..]
    const name = new InjectionToken<string>('name');
    const caption = new InjectionToken<string>('caption');
    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: name, useClass: BS},
      { provide: caption, useClass: BS}
    ]);
    this.name = this.injector.get(name);
    this.caption = this.injector.get(caption);
    console.log(this.name); // will be an instance of BS

I am really stuck here and the documentation is not helping at all.

I need this for Dynamic component Loading and Injection. Full Plunker can be found in: Plunker Dynamic Component Loading and Injection

Upvotes: 7

Views: 16300

Answers (2)

Estus Flask
Estus Flask

Reputation: 223074

get is deprecated: from v4.0.0 use Type or InjectionToken

warning refers to the fact that injector.get is generic method and expects type argument. This is exactly what Injector documentation states:

get(token: Type | InjectionToken, notFoundValue?: T): T

Considering that name string token is supposed to resolve to a string, it should be:

this.injector.get<string>(<any>'name');

String tokens are deprecated as well, and a token is expected to be either a function or InjectionToken instance.

however I don't want to useValue or useClass, what I need is the actual value injected.

All dependencies should be registered as module or component providers in order to be injected.

Upvotes: 8

Jason Goemaat
Jason Goemaat

Reputation: 29234

First you need to create an InjectionToken (here in values.ts):

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

export const PAGE_TITLE = new InjectionToken<string>('page.title');

Then you need to import it into your module and provide a value when that token is requested:

providers: [ HeroService, MessageService,
    { provide: PAGE_TITLE, useValue: "My Wonderful Title" }
],

Then you need to import that token where you want to inject the value and use @Inject():

constructor(@Inject(PAGE_TITLE) title) {
  this.title = title;
}

Sample on Stackblitz

Looking at ReflectiveInjector it says it is slow and to use Injector.create instead btw...

Upvotes: 17

Related Questions