Are there any specific pitfalls when collecting a ...
# coroutines
l
Are there any specific pitfalls when collecting a flow within a flow? I have following code:
Copy code
suspend fun readPacketFlow(): Flow<Packet> = flow {
    api.readByteFlow().collect { bytes ->
        // parse the bytes and build packets from it
        ...
        val packet: Packet = someOperation()
        emit(packet)
    }
I'm observing strange behavior. On the caller site I'm collecting the flow like:
Copy code
fun requestPacket() {
	coroutineScope {
		launch {
			dataSource.readPacketFlow()
				.onStart { Log.d("PacketFlow", "starting packet flow.") } // logged
				.onCompletion { Log.d("PacketFlow", "completing packet flow.") } // logged
				.collect {

					val packet = it as ResponsePacket

					Log.i("Received in Flow", "bytes: [${packet.bytes.toHexString()}]") // not logged
				}

			Log.i("Request", "after readPacketFlow.") // not logged
		}
    }
	Log.i("Request", "after scope.") // not logged
}
None of the logs (except the first two) are logged. I don't get what's going on here. Any ideas?
d
Yeah don't. Use an operator if you can. You can use map in your case.
l
I'm not sure what you mean. Can you please elaborate?
d
Sure, when I get to my laptop.
l
Do you mean:
Copy code
val readPacketFlow(): Flow<Packet>
    get() = api.readByteFlow().map { // do all the stuff here }
👍 1
d
Yup, exactly that.
l
ah ok cool. So isn't it common to collect a flow within a flow?
d
No, typically an operator will do the trick.
l
Thanks Dominic 🙂
@Dominaezzz Just of curiosity: I had a look into some flow operator implementations like runningFold and it seems probably common to collect a flow within a flow:
Copy code
public fun <T, R> Flow<T>.runningFold(initial: R, @BuilderInference operation: suspend (accumulator: R, value: T) -> R): Flow<R> = flow {
    var accumulator: R = initial
    emit(accumulator)
    collect { value ->
        accumulator = operation(accumulator, value)
        emit(accumulator)
    }
}
This is a general question, not specific to the case above. So to be clear, it's not a no go to do this?
d
It's okay to collect a flow within a flow but usually there's an operator that can make your code more readable, which is why I recommend not to.
👍 2