Nacho Ruiz Martin
11/18/2023, 7:15 AMstateFlow extension?
I’ve found that if you map it with:
store.stateFlow.map(::mapper).stateIn(scope, SharingStarted.Eagerly, store.state.mapper())
you fall into the everlasting problem of textfield states.
I’ve been thinking of adding an optional mapping function inside stateFlow. This would help users of MviKotlin + Decompose that want to use Coroutines all the way down.Nacho Ruiz Martin
11/18/2023, 7:16 AMstateFlow extension and modified it in my app. It looks like:
fun <State : Any, Model : Any> Store<*, State, *>.stateFlow(mapper: State.() -> Model): StateFlow<Model> =
StoreStateFlow(store = this, mapper)
private class StoreStateFlow<State : Any, Model : Any>(
private val store: Store<*, State, *>,
private val mapper: State.() -> Model,
) : StateFlow<Model> {
override val value: Model get() = store.state.mapper()
override val replayCache: List<Model> get() = listOf(store.state.mapper())
override suspend fun collect(collector: FlowCollector<Model>): Nothing {
val flow = MutableStateFlow(store.state.mapper())
val disposable = store.states(observer { flow.value = it.mapper() })
try {
flow.collect(collector)
} finally {
disposable.dispose()
}
}
}Nacho Ruiz Martin
11/18/2023, 7:16 AMstateFlow is no longer a variable, but a function.Arkadii Ivanov
11/18/2023, 10:09 AMWDYT of adding a built-in way of mapping states out of the store when usingTechnically it's possible, but's not as easy as it may look like. I.e. ideally theextension?stateFlow
value property should be cached to avoid calling the mapper every time.
you fall into the everlasting problem of textfield statesYou should use
Dispatchers.Main.immediate there as well. E.g. the scope you are passing into stateIn function should be created with Main.immediate dispatcher. And also use Main.immediate when you collect the flow. Then it should work fine.Nacho Ruiz Martin
11/18/2023, 12:18 PMArkadii Ivanov
11/18/2023, 12:19 PMNacho Ruiz Martin
11/18/2023, 12:19 PM