Nous continuons notre découverte des dernières nouveautés d’Angular 14 et Angular 15.
A partir d’angular 14, plus besoin de passer par l’injection par constructeur ! Nous allons pouvoir utiliser la method inject.
Et ça c’est vraiment extra ordinaire !
Tout part d’un context d’injection
Normalement pour faire une injection tu vas passer par le constructeur :
constructor(private readonly client: HttpClient) { }
A partir d’Angular 14, si tu respecter le context d’injection du constructeur, ou des attributs, tu vas pouvoir te passer du constructeur !
@Injectable({
providedIn: 'root'
})
export class ChildService {
private client: HttpClient = inject(HttpClient);
// constructor(private readonly client: HttpClient) { }
getAll(): Observable<PeopleResult[]> {
return this.client.get<ApiPersonResult>('https://swapi.dev/api/people').pipe(
map(item => item.results)
);
}
}
C’est extraordinaire ! Je trouve ça beaucoup plus fluide !
Comment injecter HttpClientModule dans une application standalone ?
Tu l’as sans doute remarqué, pour importer un module, global à toute ton application, tu vas rencontrer quelques différences avec ce que tu avais l’habitude avant angular 15 ?
Pour ça, Angular nous a facilité le travail avec provideHttpClient
Ca permet d’écrire un code plus clean dans le main.ts
var providers: Array<Provider | EnvironmentProviders> = [
provideRouter(mainRoutes, withDebugTracing()),
provideHttpClient()
];
bootstrapApplication(MainComponent, { providers });
Jusqu’à oublier la classe de Service
Avec le principe du context d’injection, on va pouvoir faire disparaître notre service !
Et créer une fonction qui va être appelée dans le context d’injection :
export const getAllPeople = (url: string): Observable<PeopleResult[]> => {
const client = inject(HttpClient);
return client.get<ApiPersonResult>(url).pipe(
map(item => item.results)
);
}
Ce qui nous permet de l’appeler directement dans notre Component :
export class ChildTwoComponent implements OnInit {
people$ = getAllPeople('https://swapi.dev/api/people');
}
Imagine ! Plus besoin de service pour les cas les plus simples d’appels api !
Et plus qu’à link cet attribut avec un pipe async sur ton template :
<div *ngFor="let item of people$ | async">
<b>{{item.name}}</b>
</div>
C’est vraiment une nouvelle approche de faire des composants, depuis Angular 14, grâce à inject !
Et si je te disais qu’on peut aller encore plus loin ! Il suffit de récupérer le context d’injection !
Exécuter une injection depuis le context d’injection
Prenons une fonction qui va s’appuyer sur httpClient pour récupérer la liste des fims et les afficher dans la console :
export const getFilms = (): void => {
const client = inject(HttpClient);
client.get<ApiMovieResult>('https://swapi.dev/api/films').pipe(map(item => item.results)).subscribe(items => {
console.info('movies', items);
});
}
On peut alors appeler cette fonction via un clic d’un bouton, même après la construction.
Comment ? Il suffit de récupérer l’EnvironmentInjector.
export class MainComponent {
constructor(protected readonly service: TestSingletonService,
private readonly injector: EnvironmentInjector) { }
executeActionWithInject(): void {
this.injector.runInContext(() => {
getFilms();
})
}
}
Imaginez les possibilités ! C’est vraiment puissant comme système !
(Seul bémol, ça ne fonctionne que sur des méthodes synchrones).
Yes, ça attire ta curiosité ?