https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

Scott Whitman

08/28/2021, 1:26 PM
Map used on a SharedFlow returns a Flow. Is there an equivalent function to map that will return a SharedFlow?
l

louiscad

08/28/2021, 1:48 PM
Nope, but you can use
shareIn
on it.
s

Scott Whitman

08/28/2021, 2:18 PM
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

louiscad

08/28/2021, 2:19 PM
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

Scott Whitman

08/28/2021, 3:45 PM
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

louiscad

08/28/2021, 3:46 PM
Nope, because it's not kept inside the
SharedFlow
.
s

Scott Whitman

08/28/2021, 3:53 PM
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> {...}
3 Views