3

I am developing app using MVVM pattern, Retrofit, and Rx Java. The app is showing library branches and the books available there. When the activity start, I start loading all the branches, and then for every branch, I load it books. something like this in the ViewModel:

 private val branchBooksState: MutableLiveData<Pair<Branch,<List<Books>>> = MutableLiveData()

 private val libraryBranchesState: MutableLiveData<Outcome<List<Branch>>> = MutableLiveData()

 fun libraryBranchesState(): LiveData<Outcome<List<Branch>>> = libraryBranchesState

 fun branchBooksState(): LiveData<Pair<Library,<List<Books>>> = branchBooksState 
.....

fun loadLibraryBranchesAndThiereBooks(){

 compositeDisposable.add(  
            librariesInteractor.loadAllLibrarybranches()
                    .map {
                        libraryBranchesState.postValue(it)
                        it
                    }
                    .toObservable()
                    .flatMapIterable { it }
                    .flatMap {
                        librariesInteractor.loadBranchBooks(it.id).map { bookslist -> Pair(it, bookslist) }.toObservable()
                    }
                    .subscribe { pair ->
                         // there I get pair1, pair2, pair3, pair4 
                        branchBooksState.postValue(pair)
                    })}

In the Activity, I observe the livedata in the viewModel and update the UI when the data is changed. Everything works fine but the problem in subscribe when I receive the data from the parallel request and use branchBooksState.postValue(pair) to update livedata obj, the UI is not being notified for every state. For example, in subscribe I post the values: Pair 1 Pair 2 Pair 3 Pair 4

but in the activity, I am not notifying with every change. sometimes I notified with: Pair 1 Pair 3 Pair 4, and pair 2 is missing

.......
  private val libraryBranchesState = Observer<List<Branch>> {
    // display branches
}

private val branchBooksObserver = Observer<Pair<Branch ,<List<Book>>> {
    // problem here. I get pair1 , pair3 , pair4 
   // display branch books 
 
}

   override fun onCreate(savedInstanceState: Bundle?) {
    viewModel.libarayBooksState().observe(this, branchBooksObserver)
    viewModel.libraryBranchesState().observe(this, libraryBranchesObserver)}

 override fun onStart() {
    super.onStart()
     viewModel.loadLibraryBranchesAndThiereBooks()
}

I am struggling with this. Why the Activity is not notified with every change that happens in the livedata obj. What is wrong with my code? and how to fix it?

Abeer
  • 31
  • 2

1 Answers1

0

There isn't actually anything wrong with the code;

As per the documentation: If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched. (this refers to postValue)

As LiveData skips intermediate values only the last value should be considered as the truth. Also if you wish to have all the values, add the value to a List instead and post an immutable List to the LiveData

The function can be changed to

private val yourMutableList = mutableListOf<Pair<Library,<List<Books>>>()

fun loadLibraryBranchesAndThiereBooks(){

 compositeDisposable.add(  
            librariesInteractor.loadAllLibrarybranches()
                    .map {
                        libraryBranchesState.postValue(it)
                        it
                    }
                    .toObservable()
                    .flatMapIterable { it }
                    .flatMap {
                        librariesInteractor.loadBranchBooks(it.id).map { bookslist -> Pair(it, bookslist) }.toObservable()
                    }
                    .subscribe { pair ->
                        yourMutableList.add(pair)
                        branchBooksState.postValue(yourMutableList.toList())
                    })}
Vishal Ambre
  • 403
  • 4
  • 9
  • if I add them to a list, I need to wait for all pairs to be added, then update the UI. I do not want to wait for all pairs. I want to update the ui once I received to pair value in `subscribe` @Vishal Ambre – Abeer Jul 29 '20 at 12:59
  • You should not wait for all the pairs, just post a list when a new pair is received; – Vishal Ambre Jul 29 '20 at 13:28