A versão 19 do Angular chegou trazendo novidades que prometem facilitar o desenvolvimento de aplicações reativas. As novas APIs, resource() e rxResource(), simplificam o gerenciamento de requisições assíncronas, oferecendo uma maneira mais intuitiva de lidar com dados. Com essas ferramentas, os desenvolvedores podem criar código mais limpo e eficiente.
A atualização mais recente, Angular 19.2, introduz o httpResource API, que se integra diretamente com o HttpClient, eliminando a necessidade de código repetitivo. Se você busca otimizar suas chamadas de API reativas, continue lendo para saber mais sobre o httpResource API e como ele se compara às soluções já existentes.
Signals: Uma breve revisão
Os signals representam um novo jeito de desenvolver aplicações Angular. Combinados com a abordagem Zoneless, eles melhoram o desempenho e a experiência do desenvolvedor (DX). Ao usar um signal na sua view, você informa ao Angular qual nó da árvore de componentes precisa ser atualizado. Essa reatividade resulta em atualizações mais rápidas e eficientes.
Veja um exemplo de como criar e manipular um signal no Angular:
import { Component, signal } from "@angular/core";
@Component({
selector: "my-component",
template: `
<p>{{ counter() }}</p>
<button (click)="add()">Add</button>
<button (click)="remove()">Remove</button>
<button (click)="reset()">Reset</button>
`,
})
export default class MyComponent {
counter = signal<number>(0);
add() {
this.counter.update((current) => current + 1);
}
remove() {
this.counter.update((current) => current - 1);
}
reset() {
this.counter.set(0);
}
}
Qual problema essas novas ferramentas resolvem?
No início dos signals no Angular, surgiram novos padrões, incluindo um que combinava signals com o HttpClient para gerenciar respostas de API. Uma implementação comum era assim:
import { Injectable, inject, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs';
import { API_URL, User } from './user';
@Injectable({ providedIn: 'root' })
export class ApiService {
#http = inject(HttpClient);
#response = signal<User[] | null>(null);
get users() {
return this.#response.asReadonly();
}
doApiCall(request: string = '') {
this.#http
.get<{ users: User[] }>(`${API_URL}/search?q=${request}`)
.pipe(map(({ users }) => users))
.subscribe((response) => this.#response.set(response));
}
}
Essa abordagem, embora funcional, era considerada complexa e detalhada, introduzindo código repetitivo e exigindo que os desenvolvedores gerenciassem manualmente os estados de carregamento e erro. A mistura de signals com observables também podia resultar em código mais difícil de manter e entender.
resource(): Simplificando chamadas de API assíncronas
A nova primitiva resource no Angular oferece uma maneira elegante de gerenciar chamadas de API assíncronas em aplicações baseadas em signals. Ao usar resource, você pode integrar chamadas de API reativas de forma simples, com melhor gerenciamento de estado e código mais limpo.
Veja um exemplo de como resource() pode ser usado:
import { Component, signal, resource } from "@angular/core";
@Component({
selector: "my-component",
template: `
<input (input)="search($event)" placeholder="Search user..."/>
<br />
<ul>
@let error = users.error();
@if (error) {
<p>{{ error }}</p>
}
@if (users.isLoading()) {
<p>Loading Users...</p>
}
@for (user of users.value(); track user.id) {
<li>{{ user.firstName }} {{ user.lastName }}</li>
} @empty {
<p>No Users!</p>
}
</ul>
`,
})
export default class MyComponent {
query = signal<string>("");
// The resource can be typed as follows:
// resource<response type, request type>
users = resource<User[], string>({
request: () => this.query(),
loader: async ({ request, abortSignal }) => {
const response = await fetch(`${API_URL}/search?q=${request}`, {
signal: abortSignal,
});
if (!response.ok) throw new Error("Unable to load users!");
return (await response.json()).users;
},
});
search(event: Event) {
const { value } = event.target as HTMLInputElement;
this.query.set(value);
}
}
Explorando a fundo a API resource()
A API resource() introduz dois componentes essenciais para lidar com dados assíncronos:
- request: Uma função que retorna um valor usado para o cálculo do loader. Cada vez que query() muda, a função loader é reativada, funcionando de forma similar a um computed signal.
- loader: A função onde a chamada de API é feita. Ela deve retornar uma promise, e os erros podem ser tratados como em qualquer promise padrão.
Propriedades internas de resource()
A primitiva resource vem com várias propriedades úteis, todas signals:
- value(): Retorna o valor atual da resposta do resource.
- isLoading(): Indica se o resource está carregando.
- error(): Contém o erro, se houver, encontrado durante a chamada de API.
E o rxResource()?
Enquanto resource() usa um loader baseado em promise, rxResource() oferece uma abstração similar, mas usa Observable streams. Isso o torna ideal para cenários onde sua aplicação já depende muito de RxJS ou onde Observables são a escolha preferida para lidar com dados assíncronos.
Para ilustrar, veja um exemplo de como rxResource() pode ser usado para fazer uma chamada backend aplicando operadores RxJS como distinctUntilChanged e map:
rxUsers = rxResource<User[], string | undefined>({
request: () => this.query(),
loader: ({ request }) =>
this.#http.get<{ users: User[] }>(`${API_URL}/search?q=${request}`).pipe(
distinctUntilChanged(),
map(({ users }) => users),
catchError(() => {
throw Error('Unable to load!');
})
),
});
Exemplo prático e exploração
O poder de resource() e rxResource() fica claro ao gerenciar fluxos de trabalho assíncronos complexos na sua aplicação Angular. Ao combinar signals e essas primitivas, você pode reduzir o código repetitivo, mantendo a clareza e a reatividade.
Por exemplo, você pode atualizar componentes de UI dinamicamente com base nos estados isLoading() ou error(). Também é possível criar interfaces de busca poderosas que se adaptam em tempo real à medida que o usuário interage.
Para ver esses conceitos em ação, confira este exemplo interativo no StackBlitz. Neste demo, você encontrará uma barra de busca totalmente funcional integrada com a API resource() e exemplos de como lidar com estados de carregamento, tratamento de erros e atualizações em tempo real usando signals. Sinta-se à vontade para experimentar, modificar o código e observar como a reatividade do Angular torna o processo mais simples.
Para saber mais sobre a infraestrutura em nuvem, você pode conferir este artigo sobre como a infraestrutura em nuvem impulsiona o potencial da inteligência artificial.
O uso correto da tecnologia é fundamental para obter os melhores resultados, assim como aplicar os novos recursos do Angular 19.
O que esperar do Angular 19?
Com a chegada do Angular 19, o desenvolvimento de aplicações reativas se torna mais acessível e eficiente. As novas APIs, como resource() e rxResource(), simplificam o gerenciamento de requisições assíncronas, permitindo que os desenvolvedores criem código mais limpo e fácil de manter. Além disso, a integração do httpResource API com o HttpClient elimina a necessidade de código repetitivo, tornando o processo de desenvolvimento ainda mais ágil.
Se você busca aprimorar suas habilidades em Angular, a Nvidia oferece soluções que podem impulsionar seus projetos. Confira como a GM utiliza inteligência artificial da Nvidia para robôs, carros autônomos e fábricas inteligentes e inspire-se para aplicar essas tecnologias em suas aplicações Angular.
O Angular 19 representa um avanço significativo no desenvolvimento de aplicações web, oferecendo ferramentas poderosas para lidar com dados assíncronos e criar interfaces de usuário reativas. Ao explorar as novas APIs e primitivas, os desenvolvedores podem otimizar seus fluxos de trabalho e construir aplicações mais eficientes e fáceis de manter.
Este conteúdo foi auxiliado por Inteligência Artificial, mas escrito e revisado por um humano.
Via dev.to