Hi everyone! Huge respect to JB! I have some quest...
# flow
k
Hi everyone! Huge respect to JB! I have some question about StateFlow. What if I have 2 stateFlows and non-suspend transformer function, and I’d like to create a new StateFlow like a combination of theese two, transformed by the transformer function? It seems like current api does not allow to create such a StateFlow<>.combine operator? (sorry for bad English)
w
You can combine state flows but the result would a Flow and not a StateFlow. I think it’s because let’s say you combined two `MutableStateFlow`s, and got a
StateFlow
back. It would mean that every time you set value in one of the combined (source) flows, the resulting one would need to run the transform function to provide proper
value
. But since the source flows can’t push value downstream, it’s the downstream that needs to be collecting. Just calling
combine
can’t start collecting because collection needs to happen in a scope
So I expect what you need to do is use
combine
and later
stateIn
to launch the flow, and provide the default value as well. Since you know that the two source flows are StateFlows, you can just do the same transform as for
combine
k
but I want to be able to call like this: combinedFlow.getValue() and, theoretically, I could have the value (because both state flows has their own value, and the transform function is non-suspend)
hm, it seems like the stateIn operator - is what I’m looking for)
but not exactly! stateIn requires a coroutineScope, but I don’t have one and I needn’t it. I just want to get the value
w
In that case you can create
val myValue get() = combineFun(flow1.value, flow2.value)
k
so the question is: are you planning to create some function like StateFlow<>.combine(…): StateFlow<> ?
🤷 1
r
I solved this with a helper function (can be generalised to multiple stateflows). Note that it requires a
CoroutineScope
as receiver for scheduling the transformation function itself.
Copy code
fun <T1, T2, R> CoroutineScope.combineState(
    flow1: StateFlow<T1>,
    flow2: StateFlow<T2>,
    sharingStarted: SharingStarted = SharingStarted.Eagerly,
    transform: (T1, T2) -> R
): StateFlow<R> = combine(flow1, flow2) { o1, o2 ->
    transform.invoke(o1, o2)
}.stateIn(this, sharingStarted, transform.invoke(flow1.value, flow2.value))