How to use dependency injection with strings and numbers in Angular?
You’re probably familiar with dependency injection using classes, but what about using strings, numbers, booleans, or any other object?
“Classic” dependency injection with classes/services
The nominal case of dependency injection in Angular uses injectable classes that are often called services.
Such implementation relies on having an injectable class defined like this:
import { Injectable } from '@angular/core';@Injectable({
providedIn: 'root'
})
export class MyService {
}
And then, the service class can be injected into any other class using the following constructor-based syntax:
import {Component} from '@angular/core';
import {MyService} from '../my.service';
@Component({
//...
})
export class MyComponent {
constructor(private service: MyService) {
}
While this syntax is convenient, it can’t possibly work with strings, numbers, booleans, or anything else that doesn’t have a specific class type.
Enter Injection Token
Injection tokens are the solution to the “absence of class” problem. The idea is to create an injection token object as follows:
export const MY_STRING = new InjectionToken<string>('myString');
which, in this case, is going to be injecting a string, thanks to the generic syntax.
Then in our NgModule, we can specify which value to inject, in that example, the string “test”:
@NgModule({
imports: [BrowserModule, FormsModule],
providers: [{ provide: MY_STRING, useValue: 'test' }]
})
export class AppModule {}
Note that it is also possible to have a token provided in the root injector of your Angular application, in which case a factory function is provided to instantiate that value, here “test2”:
export const MY_STRING = new InjectionToken<string>('myString', {
providedIn: 'root',
factory: () => 'test2'
});
Finally, once your injection token is defined and that you’ve provided a way to create the actual string/object/value behind it, you can inject it in any class with the following syntax:
import { Component, Inject} from '@angular/core';
import { MY_STRING } from './app.module';@Component({})
export class AppComponent { constructor(@Inject(MY_STRING) private myString: string) {}}
In other words, an injection token is a way to give a name (and a type, using generics) to a value that can then be injected just like a regular “class service”, using the @Inject decorator.
You can access this example on Stackblitz below: https://stackblitz.com/edit/angular-ivy-1uhcva
My name is Alain Chautard. I am a Google Developer Expert in Angular, as well as a consultant and trainer at Angular Training where I help web development teams learn and become comfortable with Angular.
If you enjoyed this article, please clap for it or share it. Your help is always appreciated.