How to use dependency injection with strings and numbers in Angular?

Alain Chautard
Angular Training
Published in
2 min readAug 31, 2021

--

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.

--

--