https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

spierce7

03/31/2020, 4:54 AM
If I want to output a value from
Flow
if nothing else is output, and it completes, what’s the best way to do that?
s

spierce7

03/31/2020, 5:02 AM
yeah - I know about
onCompletion
, but it doesn’t tell me if other items have been emitted.
This is what I have, but it feels overly convoluted:
Copy code
return flow {
    var isEmpty = true

    emitAll(
        baseFlow
            .onEach { isEmpty = false }
            .onCompletion {
                if (isEmpty) {
                    emit(defaultData)
                }
            }
    )
}
a

araqnid

03/31/2020, 6:35 AM
I’d do basically that, although just wrapping a
collect
rather than using
onEach
and
onCompletion
.. just a stylistic difference, I think
sth like
Copy code
fun <T> Flow<T>.orElse(fn: () -> T): Flow<T> {
  return flow {
    var isEmpty = true
    collect { value ->
      isEmpty = false
      emit(value)
    }
    if (isEmpty) emit(fn())
  }
}
e

Erik

03/31/2020, 6:40 AM
Since you must have collected the entire flow to know it's empty, why not collect it as a list first and then use a default value if the list is empty?
Copy code
val emptyFlow = emptyFlow<Int>()
val nonEmptyFlow = flowOf(1, 2, 3)
val default = listOf(0)

println(emptyFlow.toList().ifEmpty { default }) // [0]
println(nonEmptyFlow.toList().ifEmpty { default }) // [1, 2, 3]
1
e

elizarov

03/31/2020, 7:39 AM
What are you use-cases for this kind of operator? Can you, please, add more details on where you encounter this need here: https://github.com/Kotlin/kotlinx.coroutines/issues/1890
8 Views