Injection token in angular

Vinit Tomar
3 min readJul 18, 2021

--

While working in angular many developers rarely create their own injection token. I think this is because, to use an injection token we have to use the @Inject decorator and it looks like some boilerplate has been added to our code. In many scenarios, we can totally skip creating our own injection tokens by using services. This can fulfill our requirements many times however there are some use cases where we have to use our own injection token. Following are some of them

  1. For types such as interface, generic types & callback types.
  2. For differentiating between two or more similar types.
  3. As default providers.

For interface and callback types

At line 20 we are injecting an array of type Todo. If we do not use TODO_LIST injection token, then we will get an error No subtable injection token for param 'myTodos'. It is because interfaces are not available in javascript and Todo type can not be resolved at runtime.

The same error can be seen in the case of callback type AtoBConverter as we have seen for interfaces. By looking at the above examples we can say that if we are using any type with dependency injection, which is not supported by javascript, we should use our own Injection token for that type.

For differentiating between two or more similar types

Let’s consider a scenario where we want two separate lists of pending and done Todos. The type for both will be an array of type Todo . So the question that arises is how can we differentiate between these two lists while injecting them into our component. Let’s see the below example.

Here we have created PENDING_TODOS and DONE_TODOS injection token for differentiating between these two similar types and we have also created two providers, pendingTodosProvider& doneTodosProvider, for giving us the expected list of todos in our component.

As default providers

In some scenarios, a developer might forget to configure a provider for an injection token. In that case, we will get an error NullInjectorError. We can avoid this error by providing a default value for that particular injection token. This can be done by passing an object of option as the second parameter into the InjectionToken constructor. In this object, we can assign a factory function that will return a default value, if no injector is found for our injection token. Let’s have a look at the below example.

Here we have not configured any provider for TODO_LIST token. Therefor at line number 11, an empty array will be assigned to todos instead of throwing NullInjectorError. This empty array is returned by factory method defined at line number 4.

Instead of using default providers, we can use @Optional decorator while injecting TODO_LIST token and null will be assigned to todos. The problem with this approach is that if we will try to access array function such as foreach, reduce then we will get error and this might break our code.

Apart from above all use cases, there is one more benefit of using injection token. It makes our code more tree-shakable. Instead of creating a service with many helper functions, we should create create injection token for each helper function. This way if we are not using any help function in our code then it will not be included in the dist bundle.

That’s all for this article. If you like, please hit clap, or if you have some feedback to give, please comment.

--

--

Vinit Tomar
Vinit Tomar

No responses yet