Thursday, June 7, 2018

@Injectable() Angular

It’s a common misbelief that this is a required decorator on any class that we plan on injecting into a component/service in our apps. This may change however, as there is a current issue to make @Injectable() mandatory (however this is pretty fresh and may not land for a while, or ever).

When using Angular decorators, the decorated class stores metadata about itself in a format that Angular can read - this includes the metadata about what dependencies it needs to fetch and inject.

If no Angular decorator has been used on a class there is no way for Angular to read what dependencies it requires. This is why we need to use @Injectable().

If our service injects providers we must add @Injectable(), which providers no extra functionality, to tell Angular to store that metadata it needs.

Therefore, if our service looks like this:

export class UserService {
  isAuthenticated(): boolean {
    return true;
  }
}
We don’t need to decorate it to be able to inject it into a component for example, because it doesn’t inject any providers itself.

However, if our service looks like this and contains a dependency (Http):

import { Http } from '@angular/http';

export class UserService {
  constructor(private http: Http) {}
  isAuthenticated(): Observable {
    return this.http.get('/api/user').map((res) => res.json());
  }
}
This would break as the Http provider metadata would not be stored for Angular to compose it correctly.

We can simply add @Injectable() to solve this:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

@Injectable()
export class UserService {
  constructor(private http: Http) {}
  isAuthenticated(): Observable {
    return this.http.get('/api/user').map((res) => res.json());
  }
}
At this point, Angular is aware of the Http token and can supply it to http.

Source : https://toddmotto.com/angular-dependency-injection

No comments:

Followers

Link