RxJS operators

RxJS (Reactive Extensions for JavaScript) uses Observables to handle asynchronous data streams, and operators help you manipulate these streams. Operators are usually divided into creation, transformation, filtering, combination, and utility operators. Here’s a detailed overview:


1. Creation Operators

These operators are used to create Observables.

of

Emits a sequence of values you provide.

import { of } from 'rxjs';

of(1, 2, 3).subscribe(value => console.log(value));

// Output:
// 1
// 2
// 3

from

Converts an array, promise, or iterable into an Observable.

import { from } from 'rxjs';

from([10, 20, 30]).subscribe(value => console.log(value));

// Output:
// 10
// 20
// 30

2. Transformation Operators

Used to transform items emitted by an Observable.

map

Transforms each emitted value.

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

of(1, 2, 3)
  .pipe(map(x => x * 10))
  .subscribe(value => console.log(value));

// Output:
// 10
// 20
// 30

switchMap

Maps to an inner Observable, switching to the new one whenever a new value is emitted.

import { of, interval } from 'rxjs';
import { switchMap, take } from 'rxjs/operators';

of('A', 'B')
  .pipe(
    switchMap(val => interval(1000).pipe(take(3)))
  )
  .subscribe(console.log);

// Output: (each letter triggers a new interval)
// 0,1,2 for 'A'
// 0,1,2 for 'B' (switches to new Observable)

3. Filtering Operators

Filter values emitted by an Observable.

filter

Emit only values that pass a condition.

import { of } from 'rxjs';
import { filter } from 'rxjs/operators';

of(1, 2, 3, 4)
  .pipe(filter(x => x % 2 === 0))
  .subscribe(console.log);

// Output:
// 2
// 4

take

Emit only the first N values.

import { interval } from 'rxjs';
import { take } from 'rxjs/operators';

interval(1000)
  .pipe(take(3))
  .subscribe(console.log);

// Output:
// 0
// 1
// 2

4. Combination Operators

Combine multiple Observables.

merge

Combine multiple Observables concurrently.

import { merge, interval } from 'rxjs';
import { take } from 'rxjs/operators';

const obs1 = interval(1000).pipe(take(3));
const obs2 = interval(500).pipe(take(3));

merge(obs1, obs2).subscribe(console.log);

// Output: interleaved values from both observables

concat

Emit values from one Observable, then the next.

import { concat, of } from 'rxjs';

const obs1 = of(1, 2);
const obs2 = of(3, 4);

concat(obs1, obs2).subscribe(console.log);

// Output:
// 1
// 2
// 3
// 4

5. Utility Operators

Operators for side effects or additional behaviors.

tap

Perform a side effect without changing values.

import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

of(1, 2, 3)
  .pipe(
    tap(x => console.log('Before map:', x)),
    map(x => x * 2),
    tap(x => console.log('After map:', x))
  )
  .subscribe();

// Output:
// Before map: 1
// After map: 2
// Before map: 2
// After map: 4
// Before map: 3
// After map: 6

debounceTime

Delay emissions until a certain time has passed without new events (useful for search inputs).

import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';

const input = document.getElementById('search');

fromEvent(input, 'keyup')
  .pipe(
    debounceTime(500),
    map(event => event.target.value)
  )
  .subscribe(value => console.log(value));

This is just the tip of the RxJS iceberg, but these operators are among the most commonly used. With these, you can handle most async flows in a reactive style.

Leave a Reply