
GUIDE PER ASPIRANTI PROGRAMMATORI
Le Pipes in Angular
Nella precedente sezione di questa guida abbiamo visto come la AsyncPipe ci permette di estrarre il valore di un Observable in modo da renderlo visibile nel template senza gestirlo manualmente lato codice. Questo è uno dei tanti utilizzi possibili delle pipes, un costrutto molto semplice ma anche molto potente che possiamo utilizzare nelle interpolazioni e…


Vuoi avviare una nuova carriera o fare un upgrade?
Trova il corso Digital & Tech piĂą adatto a te nel nostro catalogo!
- Le direttive in Angular
- I componenti in Angular
- Il template in Angular
- Le direttive strutturali in Angular
- La content projection in Angular
- I servizi in Angular
- Le Pipes in Angular
- Routing in Angular
- Invio di form in Angular
- Built-in control flow in Angular
- Deferrable views in Angular
- Image optimization in Angular
Nella precedente sezione di questa guida abbiamo visto come la AsyncPipe ci permette di estrarre il valore di un Observable in modo da renderlo visibile nel template senza gestirlo manualmente lato codice. Questo è uno dei tanti utilizzi possibili delle pipes, un costrutto molto semplice ma anche molto potente che possiamo utilizzare nelle interpolazioni e nei data binding.
Anche se ne abbiamo giĂ visto un esempio di utilizzo, diamo una definizione formale di pipe.
Che cos’è una pipe in Angular?
Una pipe è una funzione di trasformazione di un valore, implementata secondo un certo contratto definito dal framework in modo da poter essere riconosciuta e utilizzata nei template.
La definizione funzione di trasformazione è volutamente vaga: si possono implementare pipe con ogni tipo di input e ogni tipo di output.
Per esempio, nella sezione precedente abbiamo chiamato pipe su un Observable per manipolare i dati al suo interno e ottenere la stringa JSON da mostrare a schermo, partendo da un oggetto; ebbene, per questo tipo di operazione esiste una pipe built-in molto comoda.
Vediamo come avremmo potuto usarla in app.component.ts:
import { Component, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { map } from 'rxjs'; import { AsyncPipe, JsonPipe } from '@angular/common'; @Component({ selector: 'app-root', standalone: true, imports: [AsyncPipe, JsonPipe], // <- import JsonPipe template: '<pre>{{data | async | json}}</pre>' // <- use JsonPipe }) export class AppComponent { http = inject(HttpClient); data = this.http.get('https://catfact.ninja/fact'); // <- remove pipe/map }
Rispetto al codice preesistente, è evidente che ci siamo semplificati un po’ la vita: operare sugli Observable può essere difficile, ma estraendo prima il valore con | async (si legge “pipe async“), diventa tutto più facile. Il simbolo | è chiamato pipe operator.
Benché il metodo Observable.pipe e le pipe di Angular non siano la stessa cosa, la loro omonimia non è un caso. Qualunque concatenazione di funzioni che trasformano un valore in sequenza è chiamata pipe, cioè tubo, e spesso ci si riferisce a un sistema di funzioni in pipe come ad una pipeline di funzioni.
Angular fornisce di suo tutta una serie di built-in pipes per diversi scopi, ad esempio:
- DatePipe: per formattare una Data
- UpperCasePipe: per riscrivere una stringa di testo in maiuscolo
- PercentPipe: per trasformare una value numerica in una percentuale
Le pipe possono anche accettare degli argomenti che ne configurino il comportamento; per esempio, DatePipe accetta un argomento di tipo stringa per impostare la formattazione desiderata:
import { Component } from '@angular/core'; import { DatePipe } from '@angular/common'; @Component({ selector: 'app-root', standalone: true, imports: [DatePipe], template: '<pre>{{date | date: "dd/MM/yyyy" }}</pre>' }) export class AppComponent { date = new Date(); }
Per creare una custom pipe non dobbiamo fare altro che scrivere una classe decorata con @Pipe e che implementa l’interfaccia PipeTransform;
ci facciamo, come sempre, aiutare dalla CLI:
ng generate pipe quote
Andremo a generare una semplice pipe che inserisce tra virgolette il nostro dato:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'quote', standalone: true }) export class QuotePipe implements PipeTransform { transform(value: string | null = '', quoteChar: '\'' | '"' = '"'): string { return `${quoteChar} ${value} ${quoteChar}`; } }
In app.component.ts:
import { Component } from '@angular/core'; import { DatePipe } from '@angular/common'; import { QuotePipe } from './quote.pipe'; @Component({ selector: 'app-root', standalone: true, imports: [DatePipe, QuotePipe], template: '<pre>{{date | date: "dd/MM/yyyy" | quote: "\'" }}</pre>' }) export class AppComponent { date = new Date(); }
Ma non avevamo detto che le pipe erano funzioni?
Ebbene sì, Angular implementa le pipe sotto forma di classi ma le espone al template sotto forma di funzioni che si concatenano con l’operatore |. Grazie a questa astrazione, in una pipe è possibile iniettare dei servizi via DI, ma anche conservare uno stato e gestire il ciclo di vita, come fa AsyncPipe.
Una semplice funzione non potrebbe implementare comportamenti dilazionati nel tempo, avendo un’unica esecuzione al momento della chiamata.
Le pipe pure e le pipe impure in Angular.
Le ultime pipe che abbiamo visto sono cosiddette pure, nel senso che il loro output dipende esclusivamente dal loro input. Ma noi abbiamo appena detto che una pipe class può avere uno stato, perciò questo potrebbe influenzare l’output: ecco che subentrano le pipe impure.
Annotando una pipe con pure: false indichiamo al framework che la pipe non dipende esclusivamente dall’input che arriva dal template; un esempio di pipe impura è la AsyncPipe, che riceve un solo valore Observable come input e poi detiene internamente come stato i valori estratti nel tempo, senza che questo venga mai riassegnato e dunque senza che l’input cambi.
CONTENUTI GRATUITI IN EVIDENZA
Guide per aspiranti programmatori 👨🏻‍🚀
Vuoi muovere i primi passi nel Digital e Tech? Abbiamo preparato alcune guide per aiutarti a orientarti negli ambiti piĂą richiesti oggi.