Angular InjectionToken: Dependency Injection In-Depth
Tags: angular, injectiontoken, dependencyinjection, r3injectorerror
Published: 2023-02-21 20:37:20

At first, I would like to thank **[Omer Incirkus](https://www.linkedin.com/in/%C3%B6merincirku%C5%9F/)**, who helped me write this article and was with me while I was learning, for his contributions.

---

Dependency injection is a crucial concept in Angular that enables you to create **loosely coupled** components, services, and modules. With dependency injection, you can declare a service or component once and reuse it throughout your application, which makes your code more modular, testable, and maintainable.

Angular provides different ways to inject dependencies into your components, such as constructor injection. However, sometimes you may want to inject a value that is not a class or a service instance but rather a simple configuration value, such as a string, number, or boolean. In this case, you can use the **InjectionToken** class to define a token that represents the value you want to inject.

## What is an InjectionToken in Angular?

**An InjectionToken is a class in Angular that represents a unique identifier for a dependency.** It provides a way to decouple the provider and the consumer of a dependency by allowing you to register a token with a provider and then inject the token into a consumer. The consumer can then use the token to retrieve the value of the dependency from the provider.

The InjectionToken class has a generic type parameter that specifies the type of the value that the token represents. For example, if you want to inject a string value, you can define an InjectionToken with a string type parameter:

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

export const MY_STRING_TOKEN = new InjectionToken<string>('my-string-token');
```

In this example, we define an InjectionToken named ‘**MY_STRING_TOKEN**’ with a string type parameter. The first argument of the InjectionToken constructor is a string that provides a human-readable description of the token. _This is optional, **but recommended**, as it helps with debugging and error reporting._

## How to use an InjectionToken in Angular?

To use an InjectionToken, you need to register it as a provider in the module or component where you want to use it. You can do this by defining a provider with the token and the value that you want to inject:

```typescript
import {Component, Inject, InjectionToken} from '@angular/core';

export const MY_STRING_TOKEN = new InjectionToken<string>('my-string-token');

@Component({
  selector: 'app-my-component',
  template: `<h1>{{title}}</h1>`,
  providers: [
    {provide: MY_STRING_TOKEN, useValue: 'Hello, world!'}
  ]
})
export class MyComponent {
  constructor (
    @Inject(MY_STRING_TOKEN) private title: string
  ) { }
}
```

In this scenario; **If you don’t specify InjectionToken in provider, you will get R3InjectorError**. If you want to avoid error and null injection error even though you didn’t specify it in providers, you should write InjectorToken like this:

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

export const MY_STRING_TOKEN = new InjectionToken<string>('my-string-token', {
  providedIn: 'root', // root, any or any Component or Module
  factory: () => 'Hello, world!'; // The default value of token
});
```

And in this example (the above component), we declare a component named ‘MyComponent’ and **register the ‘MY_STRING_TOKEN’ token** as a provider with a string value of ‘Hello, world!’. We use the ‘**@Inject**‘ decorator to inject the value of the ‘MY_STRING_TOKEN’ token into the component’s constructor.

When the component is instantiated, Angular uses the ‘MY_STRING_TOKEN’ token to retrieve the string value from the provider and inject it into the component’s constructor. The component can then use the injected value as needed.

You can also use InjectionToken to inject complex objects into your components, services, or modules. For example, you can define an InjectionToken that represents a configuration object:

```typescript
export interface AppConfig {
  apiUrl: string;
  environment: string;
}

export const APP_CONFIG = new InjectionToken<AppConfig>('app-config');

export const config: AppConfig = {
  apiUrl: 'http://localhost:3000',
  environment: 'dev'
};

@NgModule({
  providers: [{provide: APP_CONFIG, useValue: config}]
})
export class AppModule { }
```

In this example, we define an interface ‘AppConfig’ that describes a configuration object with two properties then it used on AppModule providers.

---

**[Check out my websites for more...](https://cagkanmert.com)**