I have a `Flow<Product>` which emits one by...
# coroutines
m
I have a
Flow<Product>
which emits one by one, how I make it to collect those in list so I could receive a list in
collect()
l
You can create a custom operator that creates an empty mutable list before collecting the source flow, and emits the list after each collected element added. You can also use
scan
.
m
what do you think of this
Copy code
fun <T> Flow<T>.intoList(): Flow<List<T>> {
    return flow {
        val bag = arrayListOf<T>()
        collect {
            bag.add(it)
        }
        emit(bag)
    }
}
s
Note that works only if the source Flow ends/completes. Otherwise, nothing will be ever emitted
m
why
s
If the source Flow does not end, your call to
collect
will suspend forever. It will keep adding items to
bag
, but
emit(bag)
will never be called in that case
• Your source Flow starts as soon as your code calls
collect
on it, and your
collect
call suspends. • The lambda provided to your
collect
call will be called each time your source/producer Flow calls
emit
. • In the mean time your call to
collect
remains suspended. • Your call to
collect
resumes when the lambda provided to your source/producer Flow returns/*ends*.
l
@Mohamed Ibrahim You need to call
emit
after each call to
add
inside the
collect
lambda.
s
That would be like a
scan
operator, emitting a growing list each time. I think he was more thinking about a final terminating (and suspending)
toList()
method on the source Flow…. but I could be wrong…
l
That one already exists @streetsofboston
s
I wasn't sure it already existed...😀 But it seems the original poster has some issue with how Flows and their collection exactly works...
m
The issue with me that if I used toList() I have to use try catch. and may I still have RxJava concepts in mind. And not breaking the stream was my purpose
I don't know if that even correct for Flow
The scan operator is very handy here is an example of it
Copy code
val toList = 
flowOf(1, 2,3).scan(emptyList<Int>()) { acc, value -> acc + value }.toList()
💯 1
s
Yup, if you are looking on how that list grows for each emission, using
scan
is a great way to do so. But if you just need get one final list of all emissions (without any intermediate ones),
toList()
is your friend, but that requires the flow to end (since a list can only contain a finite amount of items).