Map used on a SharedFlow returns a Flow. Is there ...
# coroutines
s
Map used on a SharedFlow returns a Flow. Is there an equivalent function to map that will return a SharedFlow?
l
Nope, but you can use
shareIn
on it.
s
I am aware of
shareIn
, but it requires a CoroutineScope. The class I am in doesn't have/need a CoroutineScope for anything else and I prefer not adding one as a dependency. I can also pass in a CoroutineScope as a function argument, but I would prefer to use a
val
instead of a
fun
for my library API if possible.
Copy code
public val sharedFlow: SharedFlow<Int> = TODO("some hot flow")

public val mappedSharedFlow: SharedFlow<String> = sharedFlow.map { int ->
    int.toString()
}.shareIn(
    scope = TODO("I need a CoroutineScope here"),
    started = SharingStarted.Lazily,
    replay = 0
)

public fun mapSharedFlow(coroutineScope: CoroutineScope): SharedFlow<String> = sharedFlow.map { int ->
    int.toString()
}.shareIn(
    scope = coroutineScope,
    started = SharingStarted.Lazily,
    replay = 0
)

// This doesn't seem to work
public suspend fun mapSharedFlow(): SharedFlow<String> = coroutineScope {
    return@coroutineScope sharedFlow.map { int ->
        int.toString()
    }.shareIn(
        scope = this,
        started = SharingStarted.Lazily,
        replay = 0
    )
}
I have tried to write a
sharedMap
utility function but have been unsuccessful so far.
l
You can create your own CoroutineScope
There's no way around that, because the map operator could suspend
And it therefore requires a scope where this will be run.
s
Thanks Louis. Is there any way to get the coroutine scope or context from the original sharedFlow if I created a SharedFlow extension function?
Copy code
private fun <T, R> SharedFlow<T>.mapShared(transform: suspend (T) -> R): SharedFlow<R> {
    val context: CoroutineContext = TODO("Is there a way to get the context from the SharedFlow<T>?")
    val coroutineScope = CoroutineScope(context)

    return map(transform).shareIn(
        scope = coroutineScope,
        started = SharingStarted.Lazily,
    )
}
l
Nope, because it's not kept inside the
SharedFlow
.
s
Okay, Thanks. I saw that
onSubscribed {}
has access to a coroutineContext but I don't think that helps here. It looks like I'll pass in an external CoroutineScope like
fun mapSharedFlow(coroutineScope: CoroutineScope): SharedFlow<String> {...}