Is it possible to start observation when launching...
# coroutines
d
Is it possible to start observation when launching
StateFlow
? So the case is that I have
StateFlow
in my
ViewModel
and I would like to launch some observation(e.g. User status
Flow
) but I would like to stop this observation at the same moment that I will stop observing main
StateFlow
itself so they need to be launched in the same scope. Currently I’m using combine with status observation flow but I’m ignoring events emitted by this Flow, is there a better way to handle it? Side not: I'm not using values emitted by the second flow directly so that's why I need to ignore them.
s
Copy code
val stateFlow: StateFlow<T> = flow {
  userStatusFlow.collect {
    emit(it)
  }
}
.stateIn(
  null or whatever initial value,
  WhileSubscribed(5.seconds),
  viewModelScope,
)
This will keep the userStatusFlow alive as long as there is someone subscribed to this flow (and 5 seconds after that). Is this what you’re going after? If you throw in some more code it might be easier to map it to your use case
d
Thanks for suggestion! Unfortunately it’s not exactly what I’m trying to achieve but I will share some code. I have
ViewModel
which contains private
MutableStateFlow
and public
Flow
on which I’m collecting with lifecycle scope in my
Fragment
. And that’s important that I’m not using
viewModelScope
here. The code in view model looks like this:
Copy code
private val state = MutableStateFlow<SomeState>(SomeState())
    val viewState: Flow<SomeViewState> = state
        .combineWithSideEffectFlow(observeSomeData()) // <- this is the part I'm trying to make simpler
        .map(mapper::from) // <- ignore this, just mapping
...
		private fun observeSomeData(): Flow<SomeData> {
				... 
				state.emit(...)
		}
And
combineWithSideEffectFlow
function is complicated at this moment because it uses
combine
to subscribe on the second flow using same scope as the main flow so the one from the Fragment. I’m ignoring events emitted by this observation
observeSomeData
. So what I’m trying to achieve would be something like current
.onSubscription
method but with the same scope as the
StateFlow
on which it will be called.
Copy code
val viewState: Flow<ProductDetailsViewState> = state
        .collectAlso(observeDraftOrder())
        .map(mapper::from)
r
Can't you use
combine
directly?:
Copy code
val viewState: Flow<SomeViewState> = state.combine(observeSomeData()) { state, _ -> state }.map(mapper::from)