1

I have a view with three states:

sealed class MainState(val movieList: List<Movie>) {
    class Loading(movies: List<Movie> = emptyList()) : MainState(movies)
    class Success(movies: List<Movie>) : MainState(movies)
    class Error(val throwable: Throwable, movies: List<Movie> = emptyList()) : MainState(movies)
}

These states are wrapped in a MutableLiveData and managed by a ViewModel:

class MovieListViewModel(private val movieRepo: MovieRepository) : ViewModel() {
    val stateLiveData = MutableLiveData<MainState>()
    .
    .
}

I want to integrate the query liveData to my state liveDate so that when query liveData is updated to movieList, state liveData updates to Success(movieList). How can I acheive that?

Here's how my live query looks like:

@Dao
interface MovieDAO {
@Query("SELECT * FROM Movie")
   fun getAllMovies(): LiveData<List<Movie>>
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
saiedmomen
  • 1,401
  • 16
  • 33

2 Answers2

1

If you have installed RxJava2 support for Room, I will consider following:

val stateLiveData = MutableLiveData<MainState>()

dao().getAllMovies()
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .doOnSubscribe(() -> stateLiveData.value = Loading(emptyList()))
     .subscribeBy(
         onNext = { stateLiveData.value = Success(it) }
         onError { stateLiveData(it, emptyList()) }         
      )

of course you need to change the return type of the Room query to Flowable<MainState> or Observable<MainState>.

WasabiTea
  • 389
  • 2
  • 10
  • yes it seems to work. I don't have rxjava in my project though. – saiedmomen Jan 11 '19 at 22:00
  • I'm just curious, you solution isn't lifecycle aware right? I have no experience with room rxjava support. – saiedmomen Jan 11 '19 at 22:02
  • 1
    @saiedmomen I am assuming you are using ViewModel to handle your query. LiveData is a ifecycle aware object. For the RxJava subscription, you can dispose your subscription in `onCleared()` in ViewModel. The subscription method in my answer will return `Disposable` object. You can keep it as a member variable and dispose it when the `ViewModel` gets destroyed. – WasabiTea Jan 11 '19 at 22:11
  • [Here](https://developer.android.com/reference/android/arch/lifecycle/ViewModel#oncleared) is the documentation for `onCleared()`. – WasabiTea Jan 11 '19 at 22:13
0

It could be done with the use of MediatorLiveData.

LiveData subclass which may observe other LiveData objects and react on OnChanged events from them.

The solution looks like this:

    val stateLiveData = MediatorLiveData<MainState>()

    init {
        stateLiveData.addSource(movieRepo.getAllMovies()) {
            stateLiveData.value = Success(it)
        }
    }

For more info please check this great post

saiedmomen
  • 1,401
  • 16
  • 33