Am looking at some code like following....a functi...
# coroutines
j
Am looking at some code like following....a function in a view model that creates a
StateFlow
using
stateIn
(which is called/collected from Fragment)...seemingly it work but feels like there's an issue, or at least some redundancy here but can't put my finger on why right now? (reason that's it's a suspend function instead of property is that it needs to call
suspendFunctionReturningFlowB
here but probably other ways around that....)
Copy code
suspend fun someFunction() = flowA.combine(suspendFunctionReturningFlowB()) { valA, valB ->
    <some logic>
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
It at least seems like there would only by definition be one subscriber so perhaps use of
stateIn
etc redudant?
y
Yeah - that would be my concern.
the function instead of typical val would lead to multiple calls to it, each setting up the additional accounting work for state in, and while subscribed.
j
yeah, I guess the typical use of StateFlow would be (a potentially self updating) property
y
I don't see why you can't just hide suspendFunctionReturningFlowB() inside the body of a flow {}.
it doesn't have a param from someFunction. It doesn't use results from flowA. Seems perfect for that.
j
hmm, perhaps.....
suspendFunctionReturningFlowB
returns a flow (based internally though on call to suspend function)....and that returned flow is then combined with flowA
h
but
suspendFunctionReturningFlowB
should not be suspend at all. No
Flow
returning function should be marked as
suspend
y
Copy code
val someVal = flowA.combine(flow { emitAll(suspendFunctionReturningFlowB()) }) { valA, valB ->
    <some logic>
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
j
"No
Flow
returning function should be marked as
suspend"
Probably again can be done differently but that function is returning one of 2 flows based on result of call to a suspend function.
but....I have seen that guidance as well but didn't see very clear explanation of reason for it
@yschimke yeah, looks like that would work to
y
Not sure about the rule, but it's hard to reason about when these are mixed. IMHO In the Flow world, things should be cheap and usually not have side effects until you subscribe. It's hard when APIs mix them. Seen a few ListenableFuture apis that do blocking work then return Futures.immediateValue(x). It's not that, but I think the API types (colors) should make it clear exactly how to use it. Would be interested to here the correct answer though.
j
Yeah, agreed that it's much simpler if they're not mixed like that
h
You should wrap the suspend call in
flow { if(suspending()) emitAll(flow1) else emitAll(flow2) }
then 🙂
☝️ 1
👍 2
u
Maybe you can implement suspendFunctionReturningFlow wit h flatMapLatest?