S

super-dev — full-stack

@super-dev.app · Full-stack · ★ ouvert aux missions
12,8k abonnés·47 vidéos·Actif depuis 2017

Développeur full-stack .NET / Angular avec une casquette DevOps sur Azure Cloud. Aussi à l'aise sur Flutter + Firebase. Je construis des produits, je les déploie, je les surveille.

Retour aux articles
ANGULAR
ANGULAR

Charger des données avec resource() et httpResource()

Article 2 sur 4 — Angular 21 en pratique
Zoneless, signals, resource(), @defer, SignalStore — le front moderne, en vrai.

Charger des données asynchrones a longtemps été synonyme de subscribe() manuel, de gestion d'état à la main ( loading , error , data ) et de fuites mémoire quand on oubliait un unsubscribe . Depuis Angular 21, resource() et httpResource() encapsulent tout ça dans une primitive réactive bâtie sur les signals .

Le modèle resource()

Un resource() lie une requête réactive à un loader asynchrone. Quand un signal lu dans le params change, Angular relance automatiquement le loader et annule la requête en vol via un AbortSignal . Le résultat est un objet de signals : value() , error() , status() , plus isLoading() .

TypeScript
1import { resource, signal } from '@angular/core';
2
3export class UserCard {
4 private readonly userId = signal(1);
5
6 protected readonly user = resource({
7 params: () => ({ id: this.userId() }),
8 loader: ({ params, abortSignal }) =>
9 fetch(`/api/users/${params.id}`, { abortSignal }).then((response) =>
10 response.json(),
11 ),
12 });
13
14 protected next(): void {
15 this.userId.update((id) => id + 1);
16 }
17}

Changer userId suffit : pas de subscribe , pas de takeUntilDestroyed . Le resource recharge, expose isLoading() pendant l'appel, et annule la requête précédente.

httpResource pour les appels REST

httpResource() est la variante taillée pour HttpClient : elle traverse les intercepteurs, gère le typage de la réponse et réagit aux changements d'URL. On lui passe une fonction qui retourne l'URL (ou un objet de requête complet) dérivée de signals.

TypeScript
1import { httpResource } from '@angular/common/http';
2import { signal } from '@angular/core';
3
4export class ArticleList {
5 protected readonly tag = signal<string | undefined>(undefined);
6
7 protected readonly articles = httpResource<Article[]>(() => ({
8 url: '/api/articles',
9 params: this.tag() ? { tag: this.tag() } : {},
10 }));
11}

Dans le template, on consomme les états directement, sans pipe async :

TypeScript
1@if (articles.isLoading()) {
2 <p>Chargement…</p>
3} @else if (articles.error()) {
4 <pchec du chargement.</p>
5} @else {
6 @for (article of articles.value(); track article.id) {
7 <h3>{{ article.title }}</h3>
8 }
9}

Les états et leurs pièges

status() renvoie une valeur parmi idle , loading , reloading , resolved , error et local . Deux subtilités méritent l'attention :

  • pendant un rechargement , value() garde l'ancienne donnée ( reloading ), ce qui évite

un écran blanc — pratique pour un pattern stale-while-revalidate.

  • httpResource est pensé pour la lecture (GET). Pour un POST/PUT, on reste sur

HttpClient classique : un resource se relance dès que sa requête change, ce qui n'a pas de sens pour une mutation.

Pourquoi abandonner les souscriptions manuelles

Le code RxJS impératif mélange trois préoccupations : déclencher l'appel, mapper le flux, et nettoyer. Avec resource , la dépendance devient déclarative — le loader se relance parce qu'un signal a changé, point. On supprime les BehaviorSubject de pagination, les switchMap défensifs et les finalize pour remettre loading à false . La doc officielle détaille l'API dans le guide async avec resource .

resource() ne remplace pas RxJS : il remplace la plomberie . Tu décris quoi charger et de quoi ça dépend ; Angular s'occupe du quand, de l'annulation et de l'état. Le composant redevient une simple lecture de signals.
super-dev — portfolio.app
// Continuer dans ANGULAR
Un moteur façon DOOM dans le navigateur, à trois backends
11 min • 1,4k lectures
Passer une app Angular en zoneless + signals
8 min • 4,1k lectures
@defer et le nouveau control flow : moins de JS au démarrage
6 min • 2,9k lectures