I am trying to keep a mutable state flow in my class, but when I apply any methods to it, it will be converted to an immutable Flow<T>:
class MyClass : Listener<String> {
private val source = Source()
val flow: Flow<String?>
get() = _flow
// region listener
override fun onUpdate(value: String?) {
if (value!= null) {
// emit object changes to the flow
// not possible, because the builder operators on the flow below convert it to a `Flow` and it doesn't stay as a `MutableSharedFlow` :(
_flow.tryEmit(value)
}
}
// end-region
@OptIn(ExperimentalCoroutinesApi::class)
private val _flow by lazy {
MutableStateFlow<String?>(null).onStart {
emitAll(
flow<String?> {
val initialValue = source.getInitialValue()
emit(initialValue)
}.flowOn(MyDispatchers.background)
)
}.onCompletion { error ->
// when the flow is cancelled, stop listening to changes
if (error is CancellationException) {
// is was cancelled
source.removeListener(this@MyClass)
}
}.apply {
// listen to changes and send them to the flow
source.addListener(this@MyClass)
}
}
}
Is there a way to keep the flow as a MutableStateFlow even after I apply the onCompletion/onStart methods to it?
I guess this extension function will solve your problem
public fun <T> Flow<T>.mutableStateIn(
scope: CoroutineScope,
initialValue: T
): MutableStateFlow<T> {
val flow = MutableStateFlow(initialValue)
scope.launch {
[email protected](flow)
}
return flow
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With