AsyncPipe em Angular
O AsyncPipe
é uma das classes integradas do Angular, que, ao contrário de outros pipes, é por padrão impuro. Ele permite obter o resultado de uma operação assíncrona de forma eficiente.
O AsyncPipe
monitora objetos do tipo Observable
e Promise
, retornando o valor obtido desses objetos. Quando o valor é recebido, o AsyncPipe
sinaliza ao componente que é necessário verificar mudanças. Caso o componente seja destruído, o AsyncPipe
cancela automaticamente a inscrição dos objetos Observable
e Promise
, evitando possíveis vazamentos de memória.
Vamos utilizar o AsyncPipe
no componente AppComponent
:
import { Component } from "@angular/core";
import { AsyncPipe } from "@angular/common";
import { Observable, interval } from "rxjs";
import { map } from "rxjs/operators";
@Component({
selector: "my-app",
standalone: true,
imports: [AsyncPipe],
template: `<p>Modelo: {{ phone | async }}</p>
<button (click)="showPhones()">Ver Modelos</button>`,
})
export class AppComponent {
phones = ["iPhone 15 Pro", "Xiaomi 14 Pro", "Infinix NOTE 30", "Samsung Galaxy A24", "Realme C53"];
phone: Observable<string> | undefined;
constructor() {
this.showPhones();
}
showPhones() {
this.phone = interval(500).pipe(map((i: number) => this.phones[i]));
}
}
Neste exemplo, a cada 500 milissegundos, um novo item da lista phones
é exibido no template do componente.
Benefícios do AsyncPipe
O componente não precisa se inscrever manualmente para receber dados assíncronos, processá-los ou cancelar a inscrição ao ser destruído. O AsyncPipe
realiza todas essas tarefas automaticamente.
Como o AsyncPipe
facilita a extração de dados de resultados assíncronos, ele é muito útil em cenários como carregamento de dados da rede. Vamos criar um projeto de exemplo:
helloapp/ ├── src/ │ ├── app/ │ │ ├── http.service.ts │ ├── assets/ │ │ ├── users.json │ ├── main.ts ├── angular.json ├── package-lock.json ├── package.json └── tsconfig.json
No arquivo http.service.ts
, definimos um serviço que obtém dados do servidor:
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
@Injectable()
export class HttpService {
constructor(private http: HttpClient) {}
getUsers() {
return this.http.get("assets/users.json");
}
}
Para armazenar os dados, criamos o arquivo users.json
na pasta src/assets
:
[
{
"name": "Bob",
"age": 49
},
{
"name": "Tom",
"age": 39
},
{
"name": "Alice",
"age": 34
}
]
No arquivo app.component.ts
, usamos o serviço para obter os dados:
import { Component, OnInit } from "@angular/core";
import { AsyncPipe, CommonModule } from "@angular/common";
import { Observable } from "rxjs";
import { HttpService } from "./http.service";
@Component({
selector: "my-app",
standalone: true,
imports: [AsyncPipe, CommonModule],
template: `<ul>
<li *ngFor="let user of users | async">{{ user.name }} ({{ user.age }})</li>
</ul>`,
providers: [HttpService],
})
export class AppComponent implements OnInit {
users: Observable<Object> | undefined;
constructor(private httpService: HttpService) {}
ngOnInit() {
this.users = this.httpService.getUsers();
}
}
Novamente, o carregamento dos dados é iniciado no método ngOnInit()
. No template do componente, o AsyncPipe
é aplicado aos dados recebidos:
<li *ngFor="let user of users | async">{{ user.name }} ({{ user.age }})</li>
Assim que os dados são recebidos, eles são imediatamente exibidos na página web.