I have the following UI flow when searching items from a data source:
- Display a progress indicator while retrieving from source -> assign livedata to
Outcome.loading(true)
- Display results -> assign LiveData
Outcome.success(results)
- Hide progress indicator in -> assign LiveData
Outcome.loading(false)
Now the problem is when #2 and #3 are called while the app is in the background. Resuming the app, the LiveData observers are only notified of #3 and not of #2 resulting to non-populated RecyclerView.
What is the correct way of handling this kind of situation?
class SearchViewModel @Inject constructor(
private val dataSource: MusicInfoRepositoryInterface,
private val scheduler: Scheduler,
private val disposables: CompositeDisposable) : ViewModel() {
private val searchOutcome = MutableLiveData<Outcome<List<MusicInfo>>>()
val searchOutcomLiveData: LiveData<Outcome<List<MusicInfo>>>
get() = searchOutcome
fun search(searchText: String) {
Timber.d(".loadMusicInfos")
if(searchText.isBlank()) {
return
}
dataSource.search(searchText)
.observeOn(scheduler.mainThread())
.startWith(Outcome.loading(true))
.onErrorReturn { throwable -> Outcome.failure(throwable) }
.doOnTerminate { searchOutcome.value = Outcome.loading(false) }
.subscribeWith(object : DisposableSubscriber<Outcome<List<MusicInfo>>>() {
override fun onNext(outcome: Outcome<List<MusicInfo>>?) {
searchOutcome.value = outcome
}
override fun onError(e: Throwable) {
Timber.d(e, ".onError")
}
override fun onComplete() {
Timber.d(".onComplete")
}
}).addTo(disposables)
}
override fun onCleared() {
Timber.d(".onCleared")
super.onCleared()
disposables.clear()
}
}
And below is my Outcome class
sealed class Outcome<T> {
data class Progress<T>(var loading: Boolean) : Outcome<T>()
data class Success<T>(var data: T) : Outcome<T>()
data class Failure<T>(val e: Throwable) : Outcome<T>()
companion object {
fun <T> loading(isLoading: Boolean): Outcome<T> = Progress(isLoading)
fun <T> success(data: T): Outcome<T> = Success(data)
fun <T> failure(e: Throwable): Outcome<T> = Failure(e)
}
}