BACK
Lessons29. combineLatest: the latest value from every source
Lessons · 29

29. combineLatest: the latest value from every source

combineLatest — assemble state from parts

combineLatest([a$, b$, c$]) subscribes to several sources and remembers "the latest value of each." Once every source has emitted at least once, it works like this: on any new value from any source, it emits the array [lastA, lastB, lastC].

price$:   100 ────────────────
count$:   ──────── 3 ──── 5
result$:  ─────── [100,3] [100,5]

Where you'll meet it

Any UI state assembled from several independent sources: search query + category + sort, price + quantity, form + user permissions.

The main trap

If even one source never emits anything, combineLatest stays silent. This is often solved with a startWith on each source, to give them a starting value.

Array destructuring

It's handy to unpack the [price, count] array right inside map with destructuring: map(([price, count]) => ...).

Your task

  1. In combineLatest([price$, count$]).pipe(...), add map(([price, count]) => 'Total: ' + price * count).
  2. When count$ emits after 20ms, one line comes out: Total: 300.

Deterministic check

This task's check runs in TestScheduler virtual time. If your solution is right, the console shows only Test Passed!. Don't add extra console.logs, or the check will fail.

Solution spoiler · click to reveal
const { of, timer, combineLatest, map } = Rx;

const price$ = of(100);
const count$ = timer(20).pipe(map(() => 3));

const total$ = combineLatest([price$, count$]).pipe(
  map(([price, count]) => 'Total: ' + price * count)
);
script.ts // TypeScript
CONSOLE · Console output
Hit Run to see the result...