S

super-dev — full-stack

@super-dev.app · Full-stack · ★ offen für Aufträge
12,8k Abonnenten·47 Videos·Aktiv seit 2017

Full-Stack-Entwickler .NET / Angular mit DevOps-Erfahrung auf Azure Cloud. Auch zu Hause mit Flutter + Firebase. Ich entwickle Produkte, deploye sie und überwache sie.

Zurück zu den Artikeln
ANGULAR
ANGULAR

Daten laden mit resource() und httpResource()

Artikel 2 von 4 — Angular 21 in der Praxis
Zoneless, Signals, resource(), @defer, SignalStore — modernes Frontend, für echte Projekte.

Das Laden asynchroner Daten bedeutete lange manuelles subscribe() , händisches State-Management ( loading , error , data ) und Speicherlecks, wenn man ein unsubscribe vergaß. Seit Angular 21 kapseln resource() und httpResource() all das in einer reaktiven Primitive, die auf Signals aufbaut.

Das resource()-Modell

Ein resource() verknüpft eine reaktive Anfrage mit einem asynchronen Loader . Wenn ein in params gelesenes Signal sich ändert, startet Angular den Loader automatisch neu und bricht die laufende Anfrage über ein AbortSignal ab. Das Ergebnis ist ein Signal-Objekt: value() , error() , status() sowie 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}

Es genügt, userId zu ändern: kein subscribe , kein takeUntilDestroyed . Der resource lädt neu, gibt isLoading() während des Aufrufs aus und bricht die vorherige Anfrage ab.

httpResource für REST-Aufrufe

httpResource() ist die auf HttpClient zugeschnittene Variante: Sie durchläuft die Interceptoren, verwaltet die Typisierung der Antwort und reagiert auf URL-Änderungen. Man übergibt ihr eine Funktion, die die aus Signals abgeleitete URL (oder ein vollständiges Anfrage-Objekt) zurückgibt.

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}

Im Template werden die Zustände direkt konsumiert, ohne async -Pipe:

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}

Die Zustände und ihre Tücken

status() gibt einen der Werte idle , loading , reloading , resolved , error und local zurück. Zwei Feinheiten verdienen Beachtung:

  • Während eines Neuladens behält value() die alten Daten ( reloading ), was einen weißen Bildschirm verhindert — praktisch für ein Stale-while-revalidate-Pattern.
  • httpResource ist für das Lesen (GET) gedacht. Für POST/PUT bleibt man beim klassischen HttpClient : Ein Resource startet neu, sobald sich seine Anfrage ändert, was bei einer Mutation keinen Sinn ergibt.

Warum manuelle Subscriptions aufgeben

Imperativer RxJS-Code vermischt drei Anliegen: den Aufruf auslösen, den Stream mappen und bereinigen. Mit resource wird die Abhängigkeit deklarativ — der Loader startet neu, weil sich ein Signal geändert hat, Punkt. Man entfernt die Paginierungs- BehaviorSubject s, die defensiven switchMap s und die finalize -Aufrufe, um loading wieder auf false zu setzen. Die offizielle Dokumentation beschreibt die API im Async-Guide mit resource .

resource() ersetzt nicht RxJS: Es ersetzt den Boilerplate . Du beschreibst, was geladen werden soll und wovon es abhängt; Angular kümmert sich um das Wann, den Abbruch und den Zustand. Die Komponente wird wieder zu einer einfachen Signal-Lektüre.
super-dev — portfolio.app
// Weiter in ANGULAR
Eine DOOM-artige Engine im Browser, mit drei Backends
11 min • 1,4k Aufrufe
Eine Angular-App auf zoneless + Signals umstellen
8 min • 4,1k Aufrufe
@defer und der neue Control Flow: weniger JS beim Start
6 min • 2,9k Aufrufe