switchMap

By

switchMap is one of the most useful RxJS operators because it can compose Observables from an initial value that is unknown or that change. Conceptually, it is similar to chaining then functions with Promises, but operates on streams (Promises resolve once).

Example: You have an Observable of a userID, then use it to *switch* to an HTTP request of all posts owned by that user.

file_type_js_official foo.js
import { of } from 'rxjs'; // creates an Observable with a raw value
import { switchMap } from 'rxjs/operators';


const user$ = of({ userID: 'jeffd23' });

const boats$ = user$.pipe(
    switchMap(user => {
        // return an Observable or Promise here
        return fetch(`http://.../boats/${user.userID}`)
    })
)

boats$.subscribe(console.log);
// Logs response from the API

Notice how we only need to subscribe to the boats$ Observable. It will automatically subscribe to the $user, then use the emitted userID to create the final observable of boats.

Example 2: You have 2 Observables named `nums$` and `string$`. You want to get the value of the `string$` Observable when `nums$` emits even numbers.

file_type_js_official bar.js
import { of, from } from 'rxjs';
import { switchMap, filter } from 'rxjs/operators';

const nums$ = from([1, 2, 3, 4, 5]);
const string$ = of('It\'s an even number');

// when values depend on each other we often ended up nesting subscriptions
nums$.subscribe(firstValue => {
  if(firstValue % 2 === 0) {
    strings$.subscribe(secondValue => console.log(secondValue))
  }
});


// let's refactor with switchMap
// switchMap will abandon the following values emitted from nums$, and only take values from string$

nums$.pipe(
  filter(value => value % 2 === 0),
  switchMap(value => string$)
).subscribe(value => console.log(value));
// It's an even number
// It's an even number

Nested subscriptions are not ideal and can always be refactored with operators.

Questions?

Ask questions via GitHub below OR chat on Slack #questions