RxJS Operators
Operators transform, filter, and combine Observables. They are pipes through which data flows โ map, filter, switchMap, debounceTime, and more.
Operators are functions that transform, filter, or combine Observables. They are used inside the .pipe() method.
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
of(1, 2, 3, 4, 5).pipe(
filter(n => n % 2 === 0), // Only even numbers
map(n => n * 10) // Multiply by 10
).subscribe(v => console.log(v));
// Output: 20, 40
"Operator = filter โ paani se ganda pani alag karo, clean pani niklo."
Key concept: Operators don't change the original Observable. They return a NEW Observable with the transformation applied. This is called immutability.
Chain as many operators as you want โ each one processes the output of the previous:
obs$.pipe(
filter(x => x > 10), // 1st: filter
map(x => x * 2), // 2nd: transform
debounceTime(300), // 3rd: debounce
tap(x => console.log(x)) // 4th: side effect
);Transformation operators change the values emitted by the Observable.
import { map, pluck, mapTo } from 'rxjs/operators';
// map โ transform each value (MOST USED)
of(1, 2, 3).pipe(
map(x => x * 10)
).subscribe(v => console.log(v)); // 10, 20, 30
// map with objects
of({ name: 'Chicken Biryani', price: 299 }, { name: 'Mutton Biryani', price: 399 }).pipe(
map(biryani => `${biryani.name}: โน${biryani.price}`)
).subscribe(v => console.log(v));
// "Chicken Biryani: โน299", "Mutton Biryani: โน399"
// pluck โ extract property (deprecated, use map instead)
of({ name: 'Biryani', price: 299 }).pipe(
pluck('name') // Get just the 'name' property
).subscribe(v => console.log(v)); // 'Biryani'
// mapTo โ ignore value, emit constant (rarely used)
of(1, 2, 3).pipe(
mapTo('Hello')
).subscribe(v => console.log(v)); // 'Hello', 'Hello', 'Hello'
"map = translator โ jo aata hai usko badal ke do."
map is the most commonly used operator. You'll use it constantly to transform API responses, format data for display, or extract specific properties.
Filtering operators control WHICH values pass through the pipe.
import { filter, take, takeWhile, distinctUntilChanged, debounceTime } from 'rxjs/operators';
import { from, of } from 'rxjs';
// filter โ only pass values matching condition
from([5, 12, 3, 8, 15]).pipe(
filter(x => x > 10)
).subscribe(v => console.log(v)); // 12, 15
// take(3) โ take first 3 values then auto-complete
from([10, 20, 30, 40, 50]).pipe(
take(3)
).subscribe(v => console.log(v)); // 10, 20, 30 (then complete)
// distinctUntilChanged โ skip if same as previous
from([1, 1, 2, 2, 2, 3, 1]).pipe(
distinctUntilChanged()
).subscribe(v => console.log(v)); // 1, 2, 3, 1 (consecutive duplicates removed)
// debounceTime(300) โ wait 300ms of silence before emitting
// THIS IS THE MOST USED FILTERING OPERATOR IN ANGULAR
searchInput$.pipe(
debounceTime(300) // Wait for user to pause typing
).subscribe(searchTerm => {
// Only fires after 300ms of no typing
});
"Filter = chhann โ sirf wanted values pass karo."
debounceTime is the most used filtering operator โ it's essential for search inputs, preventing API calls on every keystroke.
Combination operators work with Observables that return other Observables (higher-order Observables).
import { switchMap, mergeMap, concatMap } from 'rxjs/operators';
import { from, of } from 'rxjs';
// Imagine we have IDs and need to fetch details for each
const ids$ = of(1, 2, 3);
const fetchDetail = (id: number) => of({ id, name: `Item ${id}` });
// switchMap โ cancel previous, take LATEST (for search!)
ids$.pipe(
switchMap(id => fetchDetail(id))
).subscribe(v => console.log(v));
// Only requests for latest ID complete โ previous ones cancelled
// mergeMap โ ALL at once (order may vary)
ids$.pipe(
mergeMap(id => fetchDetail(id))
).subscribe(v => console.log(v));
// All three requests fire simultaneously, results in any order
// concatMap โ queue, one at a time (preserves order)
ids$.pipe(
concatMap(id => fetchDetail(id))
).subscribe(v => console.log(v));
// 1 finishes โ 2 starts โ 2 finishes โ 3 starts โ 3 finishes
switchMap is the MOST USED combination operator in Angular.
Use switchMap for: search-as-you-type (cancel previous), auto-complete, tab switching, any "latest value matters" scenario.
// Real-world search pattern
this.searchInput.valueChanges.pipe(
debounceTime(300), // Wait for pause
distinctUntilChanged(), // Skip if same value
switchMap(term => // Cancel previous search
this.http.get(`/api/search?q=${term}`)
)
).subscribe(results => this.results = results);Utility operators do side effects, handle errors, or add helper behavior.
import { tap, catchError, retry, delay, startWith } from 'rxjs/operators';
import { of } from 'rxjs';
// tap โ do something without changing the value (debugging, logging)
of(1, 2, 3).pipe(
tap(x => console.log('Before:', x)),
map(x => x * 10),
tap(x => console.log('After:', x))
).subscribe();
// Before: 1 โ After: 10 โ Before: 2 โ After: 20 ...
// catchError โ catch errors, return fallback
this.http.get('/api/biryani').pipe(
catchError(error => {
console.error('API Error:', error);
return of([]); // Return fallback โ app continues
})
);
// retry(3) โ retry failed observable up to 3 times
this.http.get('/api/biryani').pipe(
retry(3), // Try 3 times before giving up
catchError(() => of([])) // If still fails, return fallback
);
// startWith('LOADING') โ emit initial value before source
this.http.get('/api/biryani').pipe(
map(biryanis => ({ status: 'DONE', data: biryanis })),
startWith({ status: 'LOADING', data: [] }) // Show loading immediately
);
"Utility = side kaam โ log karo, error handle karo, retry karo."
These operators make Angular apps robust: catchError prevents crashes, retry handles network glitches, startWith improves UX.
Key Takeaways
- โ Operators are functions inside .pipe() โ immutable, return new Observable with transformation
- โ map() โ transform values (MOST POPULAR), filter() โ pass/filter values, debounceTime(ms) โ wait for pause
- โ switchMap โ cancel previous, take latest (for search, tabs); mergeMap โ all at once; concatMap โ queue
- โ tap() โ side effects without changing value; catchError() โ handle errors, return fallback
- โ retry(n) โ retry failed observable n times; startWith(initial) โ emit default before source
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login