Common RxJS Operators
Transform and combine Observable streams using the RxJS operators you'll reach for most often in Angular apps.
Piping Operators
Operators transform an Observable into a new Observable, chained together using the .pipe() method — conceptually similar to chaining array methods like .map().filter(), but for a stream over time instead of a fixed collection.
import { map, filter } from 'rxjs/operators';
const evenDoubled$ = numbers$.pipe( filter(n => n % 2 === 0), map(n => n * 2),);map and filter
map transforms each emitted value; filter only lets through values matching a condition — the most fundamental, everyday operators.
getPosts() { return this.http.get<Post[]>('/api/posts').pipe( map(posts => posts.filter(p => p.published)), );}switchMap
switchMap maps each emitted value to a new inner Observable (often another HTTP call), and automatically cancels the previous inner Observable if a new value arrives before it completes — essential for things like route-driven data fetching.
import { switchMap } from 'rxjs/operators';
this.route.params.pipe( switchMap(params => this.postsService.getPost(params['id'])),).subscribe(post => { this.post = post;});If a user navigates from /posts/1 to /posts/2 before the first request finishes, switchMap cancels the now-irrelevant request for post 1 — preventing a slower, stale response from ever overwriting the correct, newer one.
debounceTime for Search Input
debounceTime waits for a pause in emissions before letting one through — the standard pattern for a search box that shouldn't fire a request on every single keystroke.
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
this.searchControl.valueChanges.pipe( debounceTime(300), distinctUntilChanged(), switchMap(term => this.postsService.search(term)),).subscribe(results => { this.results = results;});combineLatest
combineLatest emits a combined array whenever any of the source Observables emits, once every source has emitted at least once — useful for combining several independent streams (like a filter and a page number) into one derived result.
import { combineLatest } from 'rxjs';import { map } from 'rxjs/operators';
const filteredPosts$ = combineLatest([this.category$, this.searchTerm$]).pipe( map(([category, term]) => this.filterPosts(category, term)),);Common Beginner Mistakes
mergeMap runs every inner Observable to completion without cancelling — for scenarios like route-param-driven fetches, this can let a stale, out-of-order response win; switchMap is usually the safer default.
Without it, retyping the exact same search term (e.g. after backspacing and re-typing) can trigger a redundant request debounceTime alone won't filter out.
FAQs
Well over a hundred, but a small set — map, filter, switchMap, debounceTime, combineLatest, catchError, tap — covers the vast majority of everyday Angular code.
Order matters — each operator receives the output of the one before it in the pipe, so debounceTime before switchMap behaves differently than the reverse.
Summary
A handful of RxJS operators — map, filter, switchMap, debounceTime, combineLatest — cover most real-world Angular data-flow needs. With services, DI, and RxJS covered, the next section moves into routing with the Angular Router.