Angular 19 e la Resource API: Il Futuro del Caricamento Dati Dinamico e Reattivo
Introduzione
Con la versione 19, Angular ha introdotto un nuovo potente strumento: la Resource API. Questa API semplifica il caricamento dei dati in modo dinamico e reattivo, sfruttando le caratteristiche avanzate di Angular per rendere la gestione dei dati più fluida e facile da implementare. In questo articolo, esploreremo le funzionalità principali della Resource API, partendo da esempi pratici per capire come implementarla nelle tue applicazioni Angular.
Un Esempio di Base
La nuova resource API
è pensata per semplificare la gestione delle risorse asincrone. Ecco un esempio di come funziona:
import { resource } from "@angular/core";
@Component({})
export class MyComponent {
taskResource = resource({
loader: () => Promise.resolve({ id: 1, title: "Ciao Mondo", completed: false }),
});
constructor() {
effect(() => {
console.log("Valore:", this.taskResource.value());
console.log("Stato:", this.taskResource.status());
console.log("Errore:", this.taskResource.error());
});
}
}
In questo esempio, taskResource
carica un oggetto attraverso una Promise
. La Resource API fornisce tre metodi chiave:
.value()
per ottenere il valore corrente..status()
per monitorare lo stato della richiesta (ad esempio,loading
oresolved
)..error()
per rilevare eventuali errori durante il caricamento.
Aggiornamento dei Dati Localmente
Un aspetto interessante della Resource API è la possibilità di aggiornare i dati in modo locale, senza dover fare una nuova richiesta al server. Ecco come funziona:
import { resource } from "@angular/core";
@Component({
template: `<button (click)="updateTask()">Aggiorna</button>`
})
export class MyComponent {
taskResource = resource({
loader: () => Promise.resolve({ id: 1, title: "Ciao Mondo", completed: false }),
});
updateTask() {
this.taskResource.value.update((valore) => {
if (!valore) return undefined;
return { ...valore, title: "Titolo aggiornato" };
});
}
}
In questo caso, il metodo .update()
consente di modificare localmente il valore senza necessità di interagire con il server. Lo stato cambierà in "local"
, indicando che l'aggiornamento è avvenuto in locale.
Caricamento Dati da un Server
Vediamo ora come usare la Resource API per caricare dati da un server. Ecco un esempio che utilizza l'API di esempio di jsonplaceholder
:
interface Task {
id: number;
title: string;
completed: boolean;
}
@Component()
export class MyComponent {
tasksResource = resource({
loader: () => fetch(`https://jsonplaceholder.typicode.com/todos?_limit=10`)
.then(res => res.json() as Promise<Task[]>),
});
}
Mentre i dati vengono caricati, lo stato della risorsa sarà 'loading'
. Una volta che i dati sono stati ricevuti, lo stato cambia in 'resolved'
e il valore conterrà l'array di attività.
Ricaricamento Dati
La possibilità di ricaricare i dati è fondamentale in molte applicazioni. Con la Resource API, puoi facilmente ricaricare i dati in base a un’azione dell'utente:
@Component({
template: `<button (click)="refreshData()">Ricarica</button>`
})
export class MyComponent {
tasksResource = resource({
loader: () => fetch(`https://jsonplaceholder.typicode.com/todos?_limit=10`)
.then(res => res.json() as Promise<Task[]>),
});
refreshData() {
this.tasksResource.refresh();
}
}
Il metodo refresh()
ripete la richiesta di caricamento senza sovraccaricare il server, gestendo le chiamate in modo intelligente.
Caricamento Dati con Signals
Un aspetto avanzato della Resource API è la possibilità di fare richieste reattive, legando il caricamento dei dati a un segnale. Questo permette di aggiornare automaticamente i dati ogni volta che il segnale cambia:
import { resource, signal } from "@angular/core";
@Component()
export class MyComponent {
taskId = signal(1);
taskResource = resource({
loader: () => fetch(`https://jsonplaceholder.typicode.com/todos/${this.taskId()}`)
.then(res => res.json() as Promise<Task>),
});
}
Se il taskId
cambia, la risorsa verrà ricaricata automaticamente, senza bisogno di un intervento manuale.
Utilizzo di Più Signals per Parametri Dinamici
In alcuni casi, è necessario fare richieste con più parametri dinamici. La Resource API consente di usare più segnali per gestire questo scenario:
limit = signal(10);
query = signal('');
tasksResource = resource({
request: () => ({ limit: this.limit(), query: this.query() }),
loader: ({ request, abortSignal }) => {
const { limit, query } = request;
return fetch(`https://jsonplaceholder.typicode.com/todos?_limit=${limit}&query=${query}`, { signal: abortSignal })
.then(res => res.json() as Promise<Task[]>);
},
});
Ogni cambiamento nei segnali limit
o query
farà partire una nuova richiesta automaticamente, garantendo un'esperienza utente dinamica.
Creare Risorse Riutilizzabili
Un'altra caratteristica utile della Resource API è la possibilità di separare la logica di caricamento in funzioni riutilizzabili. Ecco come fare:
import { ResourceLoaderParams } from "@angular/core";
function taskLoader({ request: id, abortSignal }: ResourceLoaderParams<number>): Promise<Task> {
return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, { signal: abortSignal })
.then(res => res.json() as Promise<Task>);
}
taskResource = resource({ request: this.taskId, loader: taskLoader });
Separando il loader
in una funzione, puoi riutilizzarlo facilmente in altri contesti o componenti.
RxResource
: La Versione con Observable
In Angular, gli Observable
sono ampiamente utilizzati per la gestione dei dati. Con rxResource
, è possibile utilizzare un modello basato su Observable
per il caricamento dei dati:
import { rxResource } from "@angular/core/rxjs-interop";
import { HttpClient } from '@angular/common/http';
@Component()
export class MyComponent {
limit = signal(10);
tasksResource = rxResource({
request: this.limit,
loader: (limit) => this.http.get<Task[]>(`https://jsonplaceholder.typicode.com/todos?_limit=${limit}`)
});
}
Questa versione sfrutta Observable
per gestire in modo reattivo le risorse, mantenendo il flusso di dati in sincronia con il ciclo di vita dell'applicazione.
Conclusioni
Angular 19, con l'introduzione della Resource API e di rxResource
, ha semplificato notevolmente la gestione dei dati in modo dinamico e reattivo. Con queste nuove funzionalità, è possibile migliorare le performance, ottimizzare le risorse e creare applicazioni più fluide e scalabili. Grazie alla gestione avanzata delle risorse asincrone, Angular si conferma come una delle scelte migliori per lo sviluppo di applicazioni moderne e reattive.