Member-only story
The 64-Slot Waiting Room: Why flatMapLatest Still Hands Your UI Yesterday's Data
flatMapLatest Still Hands Your UI Yesterday's DataNot a Medium Member? “Read For Free”
You switched accounts. The upstream Flow emitted the new user ID. flatMapLatest dutifully cancelled the old inner flow. And yet, for a few hundred milliseconds, your screen rendered the previous account's feed.
If that sounds impossible, you are in good company. The name says “latest”, and the KDoc ends with a short remark that is easy to skim past: the operator is buffered by default. This post unpacks that one sentence, shows how it turns into visible bugs on Android, and walks through fixes that you can defend in code review.
The pipeline under suspicion
Here is the shape of code you will find in many view models:
val feed: Flow<FeedRow> = accountIdFlow()
.flatMapLatest { id -> repository.observeFeed(id) }
.map { dto -> mapper.toRow(dto) } // sometimes slowCompiler note:
flatMapLatest,mapLatest, andtransformLatesthave been annotated@ExperimentalCoroutinesApiin the kotlinx.coroutines releases this post was written against. Opt in with@OptIn(ExperimentalCoroutinesApi::class)on the declaration, or module-wide with the compiler argument-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi. The snippets below omit…










