How to Collect Flow in Kotlin: Simple Guide with Examples
In Kotlin, you collect a
Flow by calling the collect terminal operator inside a coroutine. This suspending function gathers emitted values from the flow and lets you handle them one by one.Syntax
The basic syntax to collect a Flow is by calling collect { value -> } inside a coroutine scope. The collect function is a suspending function, so it must be called from a coroutine or another suspending function.
flow: The source of asynchronous data.collect: Terminal operator that triggers the flow to start emitting.{ value -> }: Lambda to handle each emitted value.
kotlin
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking fun simpleFlow(): Flow<Int> = flow { emit(1) emit(2) emit(3) } fun main() = runBlocking { simpleFlow().collect { value -> println("Received $value") } }
Output
Received 1
Received 2
Received 3
Example
This example shows how to create a flow that emits numbers and collect them to print each value. It demonstrates the use of flow, emit, and collect inside a coroutine.
kotlin
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking fun numberFlow() = flow { for (i in 1..5) { emit(i) // emit next number } } fun main() = runBlocking { numberFlow().collect { number -> println("Number: $number") } }
Output
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Common Pitfalls
Common mistakes when collecting flows include:
- Calling
collectoutside a coroutine or suspending function, causing a compile error. - Not handling cancellation properly, which can lead to leaks.
- Using blocking code inside
collectwhich can freeze the coroutine.
Always use collect inside runBlocking, launch, or other coroutine builders.
kotlin
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runBlocking fun badExample() = flow { emit(1) } fun main() { // This will cause a compile error because collect is suspending // badExample().collect { println(it) } } // Correct way: fun mainCorrect() = runBlocking { badExample().collect { println(it) } }
Quick Reference
Remember these key points when collecting flows:
- Use a coroutine scope:
collectis suspending and needs a coroutine. - Handle emissions: Use the lambda inside
collectto process each value. - Flows are cold: They start emitting only when collected.
Key Takeaways
Use the suspending function collect inside a coroutine to receive flow emissions.
Flows start emitting only when collect is called, so always collect to get data.
Never call collect outside a coroutine or suspending context to avoid errors.
Handle each emitted value inside the lambda passed to collect.
Use runBlocking or launch to create coroutine scope for collecting flows.