BACK
Lessons30. withLatestFrom: an event plus current state
Lessons · 30

30. withLatestFrom: an event plus current state

Not all sources are equal

With combineLatest all sources are "equal" — any of them can trigger an output. But often there's a primary source (a click, an event) and supporting ones (the current role, form state). You want to react only to the primary one while "peeking" at the latest values of the supporting ones.

withLatestFrom — primary plus hints

main$.pipe(withLatestFrom(extra1$, extra2$)) emits only when main$ emits. The extra streams contribute their latest values but never trigger an emission themselves.

click$:  ────── click ────── click ──
role$:   admin ──────── user ──────
result$: ────── [click, admin] ── [click, user]

A comparison

  • combineLatest — all sources equal, any emission → a result.
  • withLatestFrom — there's a "primary," and only it triggers.

Your task

  1. In saveClick$.pipe(...), add withLatestFrom(role$).
  2. Then map(([, role]) => 'Save as ' + role) — we don't need the first value (the click itself), so leave an empty slot in the destructuring.
  3. Expected output: Save as admin.

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, withLatestFrom, map } = Rx;

const saveClick$ = timer(30).pipe(map(() => 'save'));
const role$ = of('admin');

const result$ = saveClick$.pipe(
  withLatestFrom(role$),
  map(([, role]) => 'Save as ' + role)
);
script.ts // TypeScript
CONSOLE · Console output
Hit Run to see the result...