Search code examples
androidandroid-lifecycleandroid-livedataandroid-architecture-components

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.


Solution

  • 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
        }
    }