Reputation: 19824
Question:
How can I prevent my livedata immediately receiving stale data when navigating backwards? I am using the Event
class outlined here which I thought would prevent this.
Problem:
I open the app with a login fragment, and navigate to a registration fragment when a live data email/password is set (and backend call says "this is a new account go register"). If the user hits the back button during the registration Android is popping back to login. When the login fragment is recreated after a back press, it immediately fires the live data again with the stale backend response and I would like to prevent that.
LoginFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeToLoginEvent()
}
private fun subscribeToLoginEvent() {
//When a back press occurs, we subscribe again and this instantly
//fires with the same data it used to leave the screen
//(a Resource<User> with status=SUCCESS, data = null)
viewModel.user.observe(viewLifecycleOwner, Observer { response ->
Timber.i("login event observed....status:" + response?.status + ", data: " + response?.data)
binding.userResource = response
response?.let {
val status = it.status
val message = it.message
if (status == Status.SUCCESS && it.data == null) {
//This is a brand new user so we need to register now
navController()
.navigate(LoginFragmentDirections.showUserRegistration()))
}
else if(status == Status.SUCCESS && it.data != null){
goHome()
}
}
})
}
LoginViewModel.kt
private val _loginCredentials: MutableLiveData<Event<Pair<String, String>>> = MutableLiveData()
val user: LiveData<Resource<User>> = Transformations.switchMap(_loginCredentials) {
val data = it.getContentIfNotHandled()
if(data != null && data.first.isNotBlank() && data.second.isNotBlank())
interactor.callUserLoginRepo(data.first, data.second)
else
AbsentLiveData.create()
}
Upvotes: 4
Views: 2626
Reputation: 19824
Okay there's two issues here which I hope helps somebody else.
Event
class does not appear to work with transformations. I think it is because the Event is literally pointing to the wrong live data (_login_credentials
vs user
)Solution
The solution is to simply move the logic which performs the fetch one fragment deeper. So instead of listening for user credentials + login click -> fetching a user -> and then navigating somewhere, I need to listen for user credentials + login click -> navigate somewhere -> and then start subscribing for my user live data. That way I can head back to the login screen as much as I want and not subscribe to some stale live data that was never destroyed. And if I go back to login and then forwards the subscription and fragment were destroyed so I will appropriately be getting new data in that case.
Upvotes: 1