Angular 14 - Découverte de inject

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é ?

Tu souhaites aller plus loin en Angular ?

Notre adresse

1 rue du guesclin
44000 Nantes

Notre téléphone

+33 2 79 65 52 87

Société

DevToBeCurious SARL
84860163900018 - Nantes B 848 601 639