Does `.collect`-in flows inside `.collect` works t...
# flow
m
Does
.collect
-in flows inside
.collect
works this ways?
Would love to know if there’s any suggestion/feedback to improve below snippet code ❤️
Copy code
lifecycleScope.launchWhenCreated {
        val uploadsBody = mutableListOf<File>()
        files
            .asFlow()
            .map { originalFile ->
                originalFile
                    .compressImageAsFlow(this)
                    .collect { compressedImageFile ->
                        uploadsBody.add(compressedImageFile)
                    }
                uploads
            }
            .collect { result ->
                viewModel.uploadFile(this, result)
            }
}
b
1. do not use flows just for using flows, so you don't need compressImageAsFlow that simply returns single value. Create
suspend fun compressImage
instead 2. currently processing multiple files (e.g. [A, B, C]) you will end up with calling viewModel.uploadFile multiple times [A], [A, B], [A, B, C]. I don't think it is what you want 3. do not build list manually (maintaining mutableList), use terminal operator toList() to summarize:
Copy code
val compressedFiles = files
    .asFlow
    .map { originalFile -> originalFile.compressImage(..) }
    .toList()

viewModel.uploadFiles(this, compressedFiles)
I also not sure you need to use flow here, most likely list/sequence (depending on
files
type) is enough for this example
✔️ 1
today i learned 1
mind blown 1
🙏 1
m
The current approach to use
Flow
because
comporessImageAsFlow
using a
callbackFlow
(an external API). Didn’t realize that it’s possible to use
suspend
, might needs to works a little bit to refactor. 🙏
tl;dr:
suspend
-> for single value
Flow<T>
-> for collections cmiiw(?)
b
Yes, that's correct. See
suspendCancellableCoroutine
to turn an external API to suspend fun
🙏 1
today i learned 1
n
I'd tweak it a bit:
f(): T
-> for single value available/compuatable now (don't use coroutines when you don't need to)
suspend f(): T
 -> for single value available later
suspend f(): List<T>
 -> for collection that is available all at once after a bit (like a network request that returns a list)
f(): Flow<T>
-> for collection where items arrive over time (like listening for DB changes)
🙏 1
today i learned 1
m
suspend f(): List<T>
 -> for collection that is available all at once after a bit (like a network request that returns a list)
Thanks for this part. We excessively trying
f(): Flow<List<T>>
in our codebase until now for our network request. Does the
f(): Flow<T>
for network request a recommended to use? e.g: we try to listening for RecyclerView/list updates for pagination cmiiw