notquiteamonad
notquiteamonad

Reputation: 1169

Why does LiveData.getValue return null unless observe has been called?

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

Answers (2)

EpicPandaForce
EpicPandaForce

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

Doug Stevenson
Doug Stevenson

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

Related Questions