/ Angular

Angular Services : 3 Common Misconceptions About the @Injectable Decorator

With the rewrite of the Angular framework, from AngularJS to the new version, many concepts have been simplified by the Angular team.
In AngularJS we could use factories, services, providers, contants or values to define the same things, but in different ways. In Angular, you only have to learn the concept of Service and you are ready to go.

Most of the time an Angular service is just a TypeScript class decorated with @Injectable. But that doesn't allow us to define an Angular service as a TypeScript class annotated with the @Injectable decorator. Unfortunately, more often than not, people think that the two previous statements can be equated.

In this article, I will go over three common misconceptions about the @Injectable decorator.

Misconception 1: the @Injectable decorator means that the class can be injected somewhere (in a constructor)

In English, injectable can be one of two things:

  • an adjective: capable of being injected;
  • a noun: a pharmaceutical preparation that can be injected.

It is very easy to think that @Injectable implies the notion of something that can be injected somewhere because of the meaning of "injectable" in English. But that is not the case. The @Injectable decorator DOES NOT mean that a class can be injected somewhere. The term @Injectable is a little bit confusing. A better name for @Injectable could have been @CanBeInjectedThings but isn't it too long for a decorator name ?

Misconception 2: the @Injectable decorator is what makes a service a service.

In most of the tutorials or courses available on the Internet, you will find services annotated with the @Injectable decorator. If you use the Angular CLI to generate a service, you will find it decorated with @Injectable. Although it is a best practice to mark all your services with the @Injectable, many people think that this is what make a service what it is. But it's not.
What make a service a service is the fact that it is added to the providers array of either a component or a module.

Misconception 3: the @Injectable decorator is required for services

If a service has injected dependencies, it "needs" to be annotated with the @Injectable decorator. In reality, any TypeScript decorator will do the job. But we use the @Injectable decorator specifically because of the semantic given to it by the Angular team and the Angular developers.

Technically speaking, you can actually make your own decorator and use it instead of the @Injectable decorator and your services will still work. But using the @Injectable will make your intent clear to your Angular peers.

What Does the @Injectable Decorator Really Mean and Why do We Need It?

if we take a look at the Angular documentation, we can find

A marker metadata that marks a class as available to Injector for creation.

The @Injectable() decorator identifies a service class that might require injected dependencies.

First of all, you have to know that the @Injectable is only "required" if your service has injected dependencies.
To prove that, let's write a simple service that does not have injected dependencies. We do that in 3 steps:

  1. We create the service class (without a decorator)
  1. Then we add it to the providers array of a module, the root module
  1. Finally we inject our service in a component, the root component

app.component

It works. We have successfully created an Angular service without the @Injectable decorator. But things will break as soon we inject something into our service.

  1. Let's inject HttpClient into our service to fetch the data from a backend.
  1. What happens in the browser?

syntax_error-1

Our application is now broken: the Angular compiler can't resolve the HttpClient parameter.

Solving this problem is as simple as adding the @Injectable decorator to our TeamService.

app.component

We need the @Injectable decorator to make Dependency Injection work in Angular

The Angular Dependency Injection mechanism uses TypeScript types to know what to inject.

We write our Angular applications in TypeScript. Our class TeamService depends on the HttpClient service, Angular will use the type 'HttpClient' to know what need to be injected into TeamService.
But JavaScript doesn't have types, so when our code is transpiled into JavaScript, we lose that information.
The sole role of the @Injectable decorator is to make Dependency Injection work (even without TypeScript). If a class is marked with any decorator, the TypeScript compiler will emit metadata about our class providing we have emitDecoratorMetadata set to true in our tsconfig.json file. In Angular we use the @Injectable decorator for that purpose. It's a convention.

In this article, we went over three common misconceptions about the @Injectable decorator used with Angular services. Then we talked about the true meaning of the @Injectable and how it enables the Angular Dependency Injection Framework to work.
Do you know other misconceptions about the @Injectable decorator ? Please let me know in the comments.
Thank you very much for reading.

Amadou Sall

Amadou Sall

Hi I'm Amadou Sall. I am the author of this blog. I design, develop, test, deploy, and maintain web applications as well as hybrid mobile applications.

Read More