Deep Dive Into The RxJs switchMap Operator: How Does it Work?

Evelyn Taylor
4 min readDec 21, 2023

--

RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using Observables, making it easier to compose asynchronous or callback-based code.

The switchMap operator is a powerful and commonly used operator in RxJS that is used for managing asynchronous operations.

It is often used when dealing with observables that emit other observables, and you want to switch to the latest inner observable while ignoring the previous ones.

How do Angular HTTP Observables work?

Think of HTTP Observables as special streams of data. Imagine you’re ordering a pizza online.

The moment you hit the “Order” button, you’ve essentially kicked off an HTTP Observable. Here’s how it works:

  1. Cold Observables: Angular HTTP Observables are cold, implying that they remain dormant until a subscription is initiated. They won’t start emitting values until explicitly subscribed to, ensuring control over when data retrieval begins.
  2. Single Emission and Completion: Unlike long-lived Observables, HTTP Observables typically emit a single value or encounter an error. Following this emission, they promptly complete. This characteristic streamlines their usage for fetching data, making them particularly well-suited for short-lived tasks.
  3. Automatic Completion Handling: Remarkably, there’s often no need to manually unsubscribe from HTTP Observables. They automatically complete after emitting a value or encountering an error. This behavior simplifies resource management and reduces the risk of memory leaks in Angular applications.

Simulating HTTP requests

Let’s create a simple example using Angular’s HttpClient to make an HTTP request, and then we’ll use the delay operator to simulate an asynchronous delay in the Observable stream.

In this example, I'll use the of operator to create an Observable that emits a single value.

getData(): Observable<any> {
// Simulate an HTTP request with the of operator
const mockData = of({ message: 'Hello from the server!' });

// Introduce a delay of 2 seconds using the delay operator
return mockData.pipe(delay(2000));
}

In this example:

  1. The of operator creates an Observable that emits a single value, an object with the message property.
  2. The delay(2000) operator simulates a delay of 2 seconds in the Observable stream.

These observables are cold, implying that they won’t emit values unless there are active subscribers. Let’s subscribe to both observables and examine the output:

this.getData().subscribe({
next: (data) => {
console.log('Received data:', data);
},
error: (error) => {
console.error('Error occurred:', error);
}
}

The Observable emits the mock data after a 2-second delay

Introducing the Switch Map Operator

Let’s then try the switchMap operator to combine two HTTP requests, and see the result.

Observable Creation:


import {of} from "rxjs";
import {delay} from "rxjs/operators";

function simulateHttp(val: any, delayNo:number) {
return of(val).pipe(delay(delayNo));
}
const saveUser$ = simulateHttp("user saved", 1000);

Here, saveUser$ represents an observable simulating an HTTP request that saves user data.

The simulated HTTP request emits the message "user saved" after a delay of 1000 milliseconds.

switchMap Operation:

const httpResult$ = saveUser$.pipe(
switchMap(sourceValue => {
console.log(sourceValue);
return simulateHttp("data reloaded", 2000);
})
);

The switchMap operator is applied to the saveUser$ observable. It takes the emitted value from saveUser$ (in this case, "user saved") and logs it.

Then, it returns a new observable, simulateHttp("data reloaded", 2000), simulating another HTTP request for reloading data.

The switchMap ensures that the result observable (httpResult$) emits the output of the inner observable.

Subscription and Output:

httpResult$.subscribe(
console.log,
console.error,
() => console.log('completed httpResult$')
);

When we subscribe to httpResult$, it triggers a subscription to saveUser$. Once saveUser$ emits its value ("user saved"), the switchMap function is invoked.

The inner observable (simulateHttp("data reloaded", 2000)) is then subscribed to, and it emits "data reloaded" after a delay of 2000 milliseconds.

Output Result:

user saved
data reloaded
completed httpResult$

The output shows the sequence of events: “user saved” is emitted by the initial observable, followed by “data reloaded” emitted by the inner observable. Finally, the completion message for httpResult$ is logged.

Why is this operator called switchMap?

Switch:

  • What is being switched? It refers to the switching between different inner observables.
  • From and to? It doesn’t refer to a switch between the source observable and the inner observable. Instead, it denotes the ability to switch from one inner observable to another.

Map:

  • What is being mapped? It refers to the mapping of the emitted source value.
  • How is it mapped? It is mapped using the function passed to switchMap, which returns an observable.

Conclusion:

The RxJS switchMap operator is an invaluable and frequently employed tool, essential for mastering as it plays a pivotal role in implementing various use cases.

It stands out as one of the select few operators that we are likely to incorporate into virtually every application we develop.

Connect with me on Medium ✍ : https://medium.com/@Evelyn.Taylor

--

--

Evelyn Taylor

A front-end enthusiast and dedicated development engineer, eager to expand knowledge on development techniques and collaborate with others.