Faisal
Faisal

Reputation: 1472

LiveData not updating on postValue()

I have got the following UI for the search functionality.

 View (UI)   <<  ViewModel()  << LiveData(Remote)
(Search UI)      (Search VM)     Fetch data from remote

As said above, View observes a particular method in ViewModel which returns the LiveData as below:

override fun onStart() {
    super.onStart()
    viewModel.finalLiveData.observe(viewLifecycleOwner, listChangeObserver)
}

// Observer responsible for updating the UI via adapter.
private val listChangeObserver: Observer<List<User>> = Observer { users ->
      users?.let { updateUI(it) } ?: run { updateUI(emptyList()) }
}

override fun onStop() {
    viewModel.finalLiveData.removeObserver(listChangeObserver)
    super.onStop()
}

while in the ViewModel, the initSearch(searchKey:String) filters the LiveData received from remote and prepares final one for the View as blow:

// Initiates the search with supplied search keys.
fun initSearch(searchInput: String?) {

    // filtering happens in Deserializer() class
    finalLiveData = Transformations.map(FirebaseQueryLiveData(query)) {
        repository.getSearchList(it, searchInput, searchLocation)
    }
}

and the initSearch will be called from view as viewModel.initSearch(searchKey). Now, the issue is, the finalLiveData receives the value from tranformation but unfortunately the View is not updated.

But, noticed the data reflects in the View if users tries recent apps and comeback (by calling onPause() and onResume())

Is there any better way to update the observed LiveData? Thanks in advance.

Upvotes: 2

Views: 2097

Answers (2)

Faisal
Faisal

Reputation: 1472

Problem fixed.

Solution posted below. by making finalLiveData as Mutable one and using a temporary LiveData, searchLiveData, to hold the result. As and when the searchLiveData gets updated the finalLiveData will get updated.

https://www.reddit.com/r/androiddev/comments/e9to2o/livedata_updates_are_not_reflecting_in_view/fant2x9?utm_source=share&utm_medium=web2x

internal var finalLiveData = MutableLiveData<List<User>>()


fun initSearch(searchInput: String?) {
    val searchLiveData = Transformations.map(FirebaseQueryLiveData(query)) {
        repository.getSearchList(it)
    }

    (searchLiveData as LiveData<List<User>>).observeForever { users ->
        finalLiveData.value = users
    }
}

Upvotes: 1

Yang Liu
Yang Liu

Reputation: 1380

Is userListRemote the LiveData from your repo? It won't work without a lifecycleowner.

You can try to map directly to your finalLiveData instead of using the temp:

finalLiveData = Transformations.map(userListRemote, // do your mapping here)

In this way, userListRemote will use the viewLifecycleOwner of finalLiveData.

Upvotes: 2

Related Questions