switchMap

Maps each event to an inner stream and mirrors only the newest one — a fresh event cancels the previous inner stream mid-flight.

FxEvents<R> FxEvents<T>.switchMap<R>(Stream<R> Function(T a) f) // chain (events)

Lecture

The search-box bug every UI has shipped at least once: the user types da, then dart; the da request is slower; its stale results arrive last and overwrite the good ones. The fix is not to ignore the old response but to make it impossible: switchMap(f) maps each event to an inner stream and, the moment a newer event arrives, cancels the previous inner stream outright. Only the newest inner stream is ever mirrored downstream.

Cancellation-by-newer is a policy, and it is the right one exactly when older work becomes worthless once newer input exists — search, autocomplete, navigation, "load details for the selected row". It is the wrong one when every inner stream's output matters (an upload per file, say) — that is a fan-out job for the pull side's mapConcurrent, where nothing gets cancelled.

Semantics at the edges: the chain closes when the source has closed and the last inner stream completes — the source ending never cuts short work already on screen. A mapper that throws becomes an error event and the source keeps going. fxdart events layer, after Rx's switchMap.

Demo 1 · The search box, fixed

Demo 2 · The last inner stream finishes its say

Try it yourself

Exercise: autocomplete that cannot show stale suggestions.

Related: debounce — its natural upstream partner: fewer queries in, no stale results out · race — cancellation between sibling streams instead of successive ones · mapConcurrent — when every result matters, pull-side fan-out