The feature
The angular team in version 14 introduced the inject
method to play with dependency injection without needing to add a constructor. Here is an example of a dummy service that is injected:
import { Injectable } from "@angular/core";
import { Observable, of } from "rxjs";
@Injectable({ providedIn: 'root' })
export class ApiService {
list$(): Observable<any> {
return of([1,2,3]);
}
}
Furthermore, the example used in the component would be:
import { Component, inject } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from './api.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
standalone: true
})
export class AppComponent {
title = 'simple-injection';
private readonly apiService = inject(ApiService);
getList$(): Observable<any> {
return this.apiService.list$();
}
}
No need to use a constructor, which is fantastic and provides cleaner code.
The util approach
There could be situations the method is more extensive and more complicated. We can introduce the util approach by using the inject
method once again. All we have to do is to extract the method to separate functions or even files and use the inject
method there:
function getList$(): Observable<any> {
return inject(ApiService).list$().pipe(
filter(Boolean),
map(data => data.list)
);
}
And then at the component level:
list$ = getList$();
We have to remember that the inject
method can be used only in two situations:
- in a constructor, a constructor parameter and a field initializer (like above)
- factory provider:
providers: [
{provide: User, useFactory: () => {
const posts = inject(Posts);
return new User(posts);
}}
]
Summary
The inject
method is a compelling feature and can save a lot of code and introduce resuable parts of logic.
Top comments (0)