I have the following code in my Fragment, subscribing to my ViewModel's LiveData events.
viewModel.successfullyAddedEvent.observeEvent(this){
// do result handling by shared view model to the calling fragment
result.successfullyAddedEvent.postValue(Event(it))
findNavController().navigateUp()
}
viewModel.successfullyEditedEvent.observeEvent(this){
// do result handling by shared view model to the calling fragment
result.successfullyEditedEvent.postValue(Event(it))
findNavController().navigateUp()
}
viewModel.exitRequestedEvent.observeEvent(this){
when(it){
ExitReason.GetDetailsFailed -> {
Toast.makeText(context, R.string.details_load_error, LENGTH_SHORT).show()
}
ExitReason.UserCanceled -> { /* happy path */ }
}
findNavController().navigateUp()
}
I have three places in this code where I'm calling navigateUp
and I'd like to unify the navigation a bit.
It seems like it would be a code improvement to emit an ExitRequestedEvent
from each case (successful add, successful edit, error case, user cancellation) and remove calls to navigateUp
from those events, but I'm not sure about guarantees on receipt order. That is, if I was to post values for a successfullyAddedEvent
and then an exitRequestedEvent
in my viewmodel like so:
// yay my thing happened successfully, emit events
successfullyAddedEvent.postValue(Event(contentAdded))
exitRequestedEvent.postValue(Event(ExitReason.AddSuccessful))
can I be guaranteed that I'll handle the add event (which sets the result on the shared result ViewModel) before I exit this fragment, so that the calling fragment always has a result?
According to the documentation, postValue
just means posting the task to main thread if you are not on it, so unless you have setValue
somewhere in your code as well, the order should be guaranteed.
If you want to absolutely guarantee the order (even though not necessary), you can use setValue()
for that, but you have to make sure it happens on the main thread.