Marcello Galhardo
04/28/2023, 6:34 PMFlow
that let me trigger an event when an emission has been collected? I imagine it would be similar to onCompleted but triggered whenever an emission has been successfully collected (the collect lambda has been fully completed and reached the end without interruptions). Something like onCollected
or onCollectCompleted
.
My use case would be to implement the solution proposed in ViewModel One-off event antipatterns from the view model side and reduce the boilerplate.bezrukov
04/28/2023, 6:49 PM.buffer()
operator or it can be some transform operator introducing intermediate collector. Another reason is that flow is designed to be unidirectional
you should be able to achieve it with operators inversion though, instead of desired
someFlow
.onCollected { item -> //some side effect }
.collect { // collector }
Just do
someFlow
.onEach { // collector }
.onEach { // item -> //some side effect }
.collect()
If you can't do this (like desired onCollection { }
somehow must be applied on the upstream, I think the only option is to introduce the wrapper like Message(item: T, collectionSignal: Deferred<Unit>)
which will allow you to perform bi-directional communicationCasey Brooks
04/28/2023, 6:53 PMemit()
will suspend until the collector has finished processing that item. This is the core design of Flows. However, I believe this is no such guarantee if you account for things like buffering or other Flow operators.
Instead of using a Flow for one-off usecases, you might consider a Channel
instead. Using a Channel, you can send an Event to be processed, which you don’t need to manually clear once it’s been handled. Channel<Events>(RENDEZVOUS, BufferOverflow.SUSPEND)
will mean that a call to channel.send()
will suspend until the item has been processed by the UI. If the VM doesn’t need to suspend until after it’s been processed and you just need a fire-and-forget type one-off event, Channel(BUFFERED, BufferOverflow.SUSPEND)
might be preferableCasey Brooks
04/28/2023, 7:04 PMBUFFERED
channels for my one-off events, and while that doesn’t give the VM the immediate feedback that an event has actually been handled, I’ve never found that to be an issue. I have a reasonably-strong guarantee that the item will live in the channel until it’s consumed, which works even if the UI is in the background when the item gets sent, and when the UI comes back it will re-subscribe to the channel and accept that event, so it doesn’t get lostCasey Brooks
04/28/2023, 7:05 PMPablichjenkov
04/28/2023, 7:39 PMeffects
. I use it with channel.unlimmited so it buffers until memory is exhausted. In my experience using a channel has worked better than sharedflow or a custom event dispatcherMarcello Galhardo
04/28/2023, 8:13 PMDeferred
to build such a mechanism with minimum boilerplate, and that would cover my use case. Thanks for the ideas, I will play with it.
@Casey Brooks, @Pablichjenkov I used to do likewise but Manuel does a good job describing the issue with channels and ViewModels one shot, which won't be solved by changing the capacity.
That is: 1) the producer (ViewModel) sends the event, 2) the consumer (View) receives the event which is scheduled for dispatch, but then, 3) the consumer is cancelled. The event was received but never processed.
I agree the issue has low chance of happening but it may happen, and can be a problem. My goal here is to explore alternative solutions from Manuel's one. For example: the Channel sends an event, the View receivers but there is a configuration change. The event may be lost. If I misunderstood your messages, please correct me.
Casey Brooks
04/28/2023, 8:19 PMCasey Brooks
04/28/2023, 8:21 PMPablichjenkov
04/28/2023, 8:21 PMPablichjenkov
04/28/2023, 8:32 PMMarcello Galhardo
04/28/2023, 8:33 PMPablichjenkov
04/28/2023, 8:35 PMCasey Brooks
04/28/2023, 8:39 PMdewildte
04/28/2023, 8:41 PMPablichjenkov
04/28/2023, 8:43 PMColton Idle
04/28/2023, 9:42 PMPablichjenkov
04/28/2023, 10:19 PMColton Idle
04/28/2023, 10:35 PMPablichjenkov
04/28/2023, 10:51 PMKamilH
04/29/2023, 7:39 PMPablichjenkov
04/29/2023, 8:45 PMColton Idle
04/30/2023, 2:56 AMKamilH
04/30/2023, 8:58 AMColton Idle
04/30/2023, 3:32 PMKamilH
04/30/2023, 4:33 PMdewildte
05/01/2023, 12:50 PMXScreen
Composable I will also set up a XScreenController
Composable that handles navigation, ViewModels, and the WindowSizeClass
.dewildte
05/01/2023, 12:55 PMXScreen
Composable.