https://kotlinlang.org logo
#coroutines
Title
# coroutines
f

Florian

09/26/2020, 7:55 AM
I use Channels to send one-off events from my ViewModel to my fragment. What should I use for events that should only be received once at most? ConflatedChannel for some reason still allows multiple events to be sent. Right now I have this: (
receive
suspends till an event is sent over the channel, but the return type is
Unit
so I ignore the return value)
g

gildor

09/26/2020, 3:06 PM
Why "for some reason"? Conflated channel is essentially observable state, which doesn't complete (until it closed) Instead of channel I would use suspend function, which under the hood could use CompletableDeffered, it's the easiest way to have a single value which is suspended until deferred is completed
f

Florian

09/26/2020, 3:44 PM
is this suited to communicate from the ViewModel to the Fragment?
right now I use normal Channel +
receiveAsFlow
and then for events that are only supposed to happen once I use
take(1)
(just to make sure). What do you think about that?
g

gildor

09/26/2020, 3:48 PM
Yes, nothing special in communication between view model and a fragment
f

Florian

09/26/2020, 3:49 PM
Well, the special part is that the ViewModel doesn't have a reference to the Fragment
g

gildor

09/26/2020, 3:49 PM
You can use flow, but if you just need some lazy way to populate a single value, you may use CompletableDeffered Also you really don't need channel, you can use State flow directly
f

Florian

09/26/2020, 3:50 PM
afaik, StateFlow gets collected again on an orientation change
which I don't want for 1-time events
g

gildor

09/26/2020, 3:50 PM
State flow cannot be collected, it's just an observable state, it cached value, it's not different in this case comparing to conflated channel
1 time event is better encode with suspend function imo
Maybe of you provide some example what you want achieve it would be easier to discuss
But what I see you just need a suspend function, and I don't see any communication problem, fragment has suspend function, it doesn't need any reference to fragment, fragment just call a function
f

Florian

09/26/2020, 3:54 PM
I need it for events where the ViewModel decides when it's time to trigger it, and then the fragment has to do something.
this is my current approach
the corresponding Fragment is in the same package, it's a very small project
g

gildor

09/26/2020, 4:11 PM
A suspend function which suspend until the event is fine for this
Flow also fine for this
f

Florian

09/26/2020, 4:14 PM
do you have an example of that suspend function approach?
Do you mean I pass a suspend function block from my fragment to my ViewModel and then call invoke in the ViewModel?
but wouldn't this create an implicit reference to the fragment inside the ViewModel?
4 Views