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
- In
combineLatest([price$, count$]).pipe(...), addmap(([price, count]) => 'Total: ' + price * count). - 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.
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)
);