Hello, I'm playing with ballast and I would like t...
# ballast
r
Hello, I'm playing with ballast and I would like to know if I should use
send()
or
trySend()
to dispatch inputs?
c
It’s basically just passing straight-through to a Channel’s same methods, so it’s the same rules as would apply there. Typically, you’d want to
send()
so it suspends if the buffer is full to give your app backpressure, but
trySend()
is there for cases where you’re sending an Input to the ViewModel from a non-suspending context (like a Compose callback or Android OnClickListener)
r
Do I understand correctly that when I use
trySend()
from the button click listener and it doesn't work, the user will have the feeling that the button does not work?
c
Yes, but the same would be true if you launched a coroutine from that click listener and sent the Input using
send()
.
trySend()
returns a
ChannelResult
that can give you immediate feedback on whether the Input will be processed or was dropped, so you can respond in the UI, if needed. However, the best situation is obviously that Inputs are not silently dropped, and that they’re handled immediately so there’s no lag between the click and the processing of that Input. There are several different Input Strategies you can choose from to help tailor exactly what happens when a new Input is sent to the ViewModel. The default is
LifoInputStrategy
, where any currently-running work is cancelled so new Inputs are processed immediately, and in this strategy
trySend()
will never fail and
send()
will never suspend
And I just realized that this is missing from the docs there, but the InputStrategy is set in the ViewModel’s Configuration:
Copy code
BallastViewModelConfiguration.Builder()
    .apply {
        inputStrategy = FifoInputStrategy()
    }
    .withViewModel(...)
    .build()