1

I'm having a curious issue when dealing with flatMapLatest and emptyFlow as well as firstOrNull.

Scenario A:

val dataFlow: Flow<Boolean> = emptyFlow()

launch {
    val data = dataFlow.firstOrNull()  // returns data = null
}

Scenario B:

val rootFlow: MutableStateFlow<Boolean?> = MutableStateFlow(null)
val dataFlow: Flow<Boolean> = rootFlow.flatMapLatest {
    emptyFlow()
}

launch {
    val data = dataFlow.firstOrNull()  // blocks and does not return any value
}

So my question would be, why does firstOrNull not return any value in Scenario B. I'm seeing that flatMapLatest is being called with the initial null value of the mutable state flow.

0

1 Answer 1

1

rootFlow is a StateFlow which means it never ends.

Your dataFlow is a transformation of rootFlow so it will not end until source flow ends.

That means in this case dataFlow.firstOrNull() will suspend forever as it keeps transforming each value of rootFlow into empty flows.

Sign up to request clarification or add additional context in comments.

4 Comments

To emphasize, flow transformations do not replace the original flow, which is the reason the StateFlow's not-completing characteristic is kept and firstOrNull() never returns. This is different from the Collection transformations like emptyList().map() which returns a new list that is entirely independent from the original list. This different behavior isn't that obvious on first glance and probably the reason for op's confusion.
My confusion was kinda related to the doc of firstOrNull saying: The terminal operator that returns the first element emitted by the flow and then cancels flow's collection. Returns null if the flow was empty. Especially the last sentence. So I assumed it should return null because the flow that is returned is empty, but I guess this is related to the whole upstream instead.
@robyn You don't "return" an empty flow - its flatmap so its values are returned instead. In reality your dataFlow never emits any values.
Got it, then I also misunderstood firstOrNull in the sense I though it returns null if there is no first element, but it as I understand now it either returns the first element or null if the flow gets terminated. And if its not terminated it will just keep suspending.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.