Reputation: 1169
I have a ViewModel
which has a property of type LiveData<UserData>
, being read from a Room database.
Its code is as follows:
class UserDataViewModel(application: Application) : AndroidViewModel(application) {
private val userDataDao: UserDataDao = AppDatabase.getInstance(application).dao()
val userData: LiveData<UserData?> = userDataDao.getUserData()
}
In the associated activity, I get a reference to the view model:
private val viewModel: UserDataViewModel by viewModels()
In that activity, I need to get the value of the UserData
on a button click:
private fun handleClick(view: View) {
viewModel.userData.value?.let {
// do stuff if the userData is present
}
}
Now in theory, unless the user presses the button before the data has been loaded, this should never be null.
However, as the code stands, the call to viewModel.userData.value
is always null and the let
block never executes.
But, if I add this statement in onCreate
, the let
block in the click handler executes as desired:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.userData.observe(this, Observer {
// do nothing
})
}
My question is: why do I need to call the observe function, even if I'm doing nothing with a change event, to get valid responses from LiveData::getValue
?
Upvotes: 3
Views: 3201
Reputation: 81539
My question is: why do I need to call the observe function, even if I'm doing nothing with a change event, to get valid responses from LiveData::getValue?
Because the ComputableLiveData
returned from the Room DAO only executes the query if the LiveData has at least one active observer (inside LiveData.onActive()
). Then it runs asynchronously on a different thread, and at some point in the future it will be posted into the LiveData.
Upvotes: 6
Reputation: 317467
You do not need to call observe()
in order to get a LiveData to give up a value other than null. LiveData always contains and yields null initially until something sets its value. If you don't want this initial null value, then you should immediately set it to something else instead, before making the LiveData available to any other components. If you want to know when it first contains a non-null value, you will need to use an observer.
Upvotes: 1