São funções puras que transformam, filtram ou combinam streams de dados de em Observables.
O .pipe() é usado para encadear operadores, tipo uma composição.
todosPedidos$ = this.pedidoService.getPedidos();
totalPendentes$ = this.todosPedidos$.pipe(
map(pedidos => pedidos.filter(p => p.status === 'PENDENTE')),
map(pendentes => pendentes.length)
);Operadores de Transformação
map
Transforma cada valor emitido aplicando uma função.
nomes$ = this.usuarios$.pipe(
map(users => users.map(u => u.nome))
);
produtosComDesconto$ = this.produtos$.pipe(
map(produtos => produtos.map(p => ({
...p,
preco: p.preco * 0.9
})))
);switchMap
Cancela a requisição anterior e faz uma nova. Usado em buscas e navegação.
// Busca que cancela requisições anteriores (para digitação)
resultados$ = this.buscaControl.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(termo => this.searchService.buscar(termo))
);
detalhes$ = this.idSelecionado$.pipe(
switchMap(id => this.api.getDetalhes(id))
);mergeMap (ou flatMap)
Executa múltiplas requisições em paralelo sem cancelar as anteriores.
uploadArquivos(arquivos: File[]) {
return from(arquivos).pipe(
mergeMap(arquivo => this.uploadService.upload(arquivo)),
toArray()
);
}concatMap
Executa requisições em sequência, aguardando a anterior terminar.
processarPedidos(pedidos: Pedido[]) {
return from(pedidos).pipe(
concatMap(pedido => this.api.processar(pedido))
);
}Operadores de Filtragem
filter
usuariosAtivos$ = this.usuarios$.pipe(
filter(users => users.filter(u => u.ativo))
);
valoresAltos$ = this.numeros$.pipe(
filter(n => n > 100)
);distinctUntilChanged
Emite apenas quando o valor muda em relação ao anterior.
// Evita requisições duplicadas em inputs (digitação)
busca$ = this.searchControl.valueChanges.pipe(
distinctUntilChanged(),
switchMap(termo => this.api.buscar(termo))
);debounceTime
buscaOtimizada$ = this.searchControl.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(termo => this.api.buscar(termo))
);take / takeUntil
Limita a quantidade de emissões ou cancela baseado em outro Observable.
primeiros$ = this.stream$.pipe(take(5));
// Cancela quando componente é destruído
export class MeuComponent implements OnDestroy {
private destroy$ = new Subject<void>();
dados$ = this.api.getDados().pipe(
takeUntil(this.destroy$)
);
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}Operadores de Combinação
combineLatest
Combina múltiplos Observables (usa sempre o último valor de cada um), emitindo sempre que qualquer um emite.
// Filtro combinado
produtosFiltrados$ = combineLatest([
this.categoriaControl.valueChanges,
this.precoControl.valueChanges,
this.produtos$
]).pipe(
map(([categoria, precoMax, produtos]) =>
produtos.filter(p =>
p.categoria === categoria && p.preco <= precoMax
)
)
);Operadores Utilitários
tap
Executa efeitos colaterais sem modificar o stream.
dados$ = this.api.getDados().pipe(
tap(dados => console.log('Dados recebidos:', dados)),
tap(dados => this.loading = false),
map(dados => this.transformar(dados))
);catchError
usuarios$ = this.api.getUsuarios().pipe(
catchError(error => {
console.error('Erro ao buscar usuários:', error);
this.notificacao.erro('Falha ao carregar dados');
return of([]);
})
);
dadosComRetry$ = this.api.getDados().pipe(
retry(3), // Tenta 3 vezes antes do catch
catchError(error => of(null))
);