Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 714
Royalsmed Avatar asked Mar 09 '18 21:03

Royalsmed


2 Answers

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...

like image 94
Jason Goemaat Avatar answered Oct 28 '22 07:10

Jason Goemaat


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.

like image 28
Estus Flask Avatar answered Oct 28 '22 09:10

Estus Flask