Referência de Operadores RxJS
A Referência de Operadores RxJS em Angular é um guia avançado para gerenciar fluxos de dados assíncronos e implementar padrões reativos em aplicações modernas. RxJS (Reactive Extensions for JavaScript) fornece uma coleção de operadores para transformar, filtrar e combinar Observables, permitindo que desenvolvedores manipulem o estado da aplicação de forma previsível e eficiente. Em Angular, os operadores RxJS, como map, filter, switchMap e mergeMap, são essenciais para evitar prop drilling e re-renders desnecessários, garantindo uma gestão eficiente do ciclo de vida dos componentes e da propagação de dados.
Este conteúdo mostra quando e como aplicar operadores RxJS em componentes Angular, seja para lidar com requisições HTTP, eventos de usuários ou streams de WebSocket. Através de exemplos práticos, o leitor aprenderá a construir componentes reutilizáveis, manter o estado centralizado e otimizar a performance da aplicação. Também será abordado como integrar RxJS ao fluxo de dados do Angular, utilizando lifecycle hooks e técnicas avançadas de tratamento de erros e otimização.
Ao final deste material, o desenvolvedor compreenderá os principais operadores RxJS aplicados em projetos Angular, conseguirá aplicar práticas recomendadas para evitar problemas comuns como mutações de estado e má performance, e estará preparado para criar SPAs modernas e escaláveis.
Exemplo Básico
typescriptimport { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
@Component({
selector: 'app-rxjs-basic',
template: ` <h2>Exemplo de Operadores RxJS</h2> <ul> <li *ngFor="let item of filteredData">{{ item }}</li> </ul>
`
})
export class RxjsBasicComponent implements OnInit {
rawData$: Observable<number[]> = of([1, 2, 3, 4, 5, 6]);
filteredData: number[] = [];
ngOnInit(): void {
this.rawData$
.pipe(
filter(data => data.length > 0),
map(data => data.filter(num => num % 2 === 0))
)
.subscribe(result => this.filteredData = result);
}
}
Neste exemplo, o componente RxjsBasicComponent demonstra como usar Observables e operadores básicos do RxJS no Angular. rawData$
é um Observable que emite um array de números. O operador filter
garante que o array não vazio seja processado, enquanto map
filtra apenas os números pares. O método subscribe
atualiza a propriedade filteredData
, que é exibida no template.
Este exemplo integra o fluxo reativo ao ciclo de vida do Angular através do hook ngOnInit
. A utilização de operadores RxJS previne prop drilling e re-renders desnecessários, promovendo um estado previsível e fácil de manter. Esse padrão é aplicável em cenários reais, como consumo de APIs ou manipulação de eventos do usuário, garantindo componentes reativos e performáticos.
Exemplo Prático
typescriptimport { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { switchMap, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-user-list',
template: ` <h2>Lista de Usuários</h2> <div *ngIf="loading">Carregando dados...</div> <ul> <li *ngFor="let user of users">{{ user.name }}</li> </ul> <div *ngIf="error">{{ error }}</div>
`
})
export class UserListComponent implements OnInit {
users: any[] = [];
loading = false;
error: string | null = null;
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.loading = true;
this.http.get<any[]>('[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)')
.pipe(
tap(() => this.loading = false),
switchMap(data => of(data.filter(user => user.id % 2 === 0))),
catchError(err => {
this.error = 'Erro ao carregar dados';
this.loading = false;
return of([]);
})
)
.subscribe(result => this.users = result);
}
}
Advanced Angular Implementation
typescriptimport { Injectable, Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { debounceTime, switchMap, map, catchError } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ProductService {
private searchTerm$ = new BehaviorSubject<string>('');
constructor(private http: HttpClient) {}
setSearchTerm(term: string) {
this.searchTerm$.next(term);
}
getFilteredProducts(): Observable<any[]> {
return this.searchTerm$.pipe(
debounceTime(300),
switchMap(term =>
this.http.get<any[]>('[https://api.example.com/products').pipe(](https://api.example.com/products'%29.pipe%28)
map(products => products.filter(p => p.name.includes(term))),
catchError(() => of([]))
)
)
);
}
}
@Component({
selector: 'app-product-list',
template: ` <input type="text" (input)="onSearch($event.target.value)" placeholder="Buscar produto"> <ul> <li *ngFor="let product of products$ | async">{{ product.name }}</li> </ul>
`
})
export class ProductListComponent implements OnInit {
products$: Observable<any[]> = of([]);
constructor(private productService: ProductService) {}
ngOnInit(): void {
this.products$ = this.productService.getFilteredProducts();
}
onSearch(term: string) {
this.productService.setSearchTerm(term);
}
}
Este exemplo avançado utiliza BehaviorSubject e debounceTime para implementar uma pesquisa reativa. O operador switchMap garante que apenas a última busca seja processada, enquanto catchError trata erros de forma robusta. Separar Service e Component mantém o estado centralizado, mantendo os componentes leves e reutilizáveis.
O uso do async Pipe no template gerencia automaticamente as subscriptions, prevenindo memory leaks. Este padrão é essencial para SPAs modernas, integrando Dependency Injection, lifecycle hooks e gerenciamento reativo de estado, demonstrando boas práticas de Angular e performance otimizada.
Boas práticas e armadilhas comuns em Angular:
Ao usar operadores RxJS, mantenha os components limpos e reutilizáveis. Use Services para gerenciar estado, async Pipe para binding direto no template, e tap para efeitos colaterais. Evite prop drilling e re-renders desnecessários.
Erros comuns incluem mutação direta do estado, ausência de tratamento de erros em requisições HTTP e uso inadequado de switchMap/mergeMap. Para otimização, use debounceTime e distinctUntilChanged. CatchError garante segurança e estabilidade, e tap/Angular DevTools auxiliam no debugging.
📊 Referência Completa
Operator | Description | Syntax | Example | Notes |
---|---|---|---|---|
map | Transforma valores do Observable | observable.pipe(map(val => transform(val))) | of(1,2,3).pipe(map(x => x*2)) | Modifica o estado |
filter | Filtra valores do Observable | observable.pipe(filter(val => condition(val))) | of(1,2,3).pipe(filter(x => x>1)) | Controla atualização do UI |
switchMap | Substitui Observable anterior | observable.pipe(switchMap(val => newObs)) | http.get('/api').pipe(switchMap(res => http.get('/api2'))) |
📊 Complete Angular Properties Reference
Property | Values | Default | Description | Angular Support |
---|---|---|---|---|
async | Observable | null | Binding direto de Observable no template | Angular 2+ |
BehaviorSubject | Subject | null | Armazena e emite valor atual | Angular 2+ |
pipe | Function | – | Composição de operadores | Angular 2+ |
subscribe | Function | – | Inicia Observable | Angular 2+ |
tap | Function | – | Efeitos colaterais | Angular 2+ |
catchError | Function | – | Tratamento de erros | Angular 6+ |
switchMap | Function | – | Substituição de Observable | Angular 5+ |
mergeMap | Function | – | Mesclagem de Observables | Angular 5+ |
debounceTime | Number | 0 | Atraso na emissão de valores | Angular 5+ |
distinctUntilChanged | Function | – | Evita valores repetidos | Angular 5+ |
shareReplay | Number | 1 | Compartilhamento e caching | Angular 5+ |
startWith | Value | – | Valor inicial | Angular 5+ |
Resumo e próximos passos:
Compreender a Referência de Operadores RxJS no Angular capacita o desenvolvedor a gerenciar fluxos assíncronos, construir components reutilizáveis e otimizados e criar SPAs escaláveis. É fundamental para projetos enterprise-level e performance-critical.
Para aprofundamento, explore operadores avançados como exhaustMap, bufferTime e window, e frameworks de gerenciamento de estado como NgRx e Akita. Pratique o uso de async Pipe, lifecycle hooks e tratamento de erros para garantir estabilidade. A prática contínua, estudo da documentação oficial e aplicação em projetos reais consolidam a expertise em RxJS com Angular.
🧠 Teste Seu Conhecimento
Teste Seu Conhecimento
Desafie-se com este questionário interativo e veja o quão bem você entende o tópico
📝 Instruções
- Leia cada pergunta cuidadosamente
- Selecione a melhor resposta para cada pergunta
- Você pode refazer o quiz quantas vezes quiser
- Seu progresso será mostrado no topo