How to use switchIfEmpty RxJava
Solution 1
As @Kiskae mentioned, it's the fact that I am confusing an empty list with an empty Observable. Therefore, I have used the following which is what I want:
public void onViewLoad(boolean hideLocks) {
Observable.just(settingsRatingRepository.getRatingsFromDB())
.flatMap(settingsRatings -> {
if (settingsRatings.isEmpty()) {
return settingsRatingRepository.getSettingsRatingModules();
} else {
return Observable.just(settingsRatings);
}
})
.compose(schedulerProvider.getSchedulers())
.subscribe(ratingsList -> {
view.loadRatingLevels(ratingsList, hideLocks);
}, this::handleError);
}
Solution 2
Observable#toList()
returns a single element. If the observable from which it gets its elements is empty, it will emit an empty list. So by definition the observable will never be empty after calling toList()
.
Solution 3
switchIfEmpty
will only be called when your observer completes without emitting any items.
Since you are doing toList
it will emit list object. Thats why your switchIfEmpty
is never getting called.
If you want to get data from cache and fallback to your api if cache is empty, use concat
along with first
or takeFirst
operator.
For example:
Observable.concat(getDataFromCache(), getDataFromApi())
.first(dataList -> !dataList.isEmpty());
blackpanther
Skills: Java, Kotlin, Groovy Mobile: Android MVVM / MVP Android architectures Retrolambda, Java 8 RxJava 1 & 2 - love beautiful Presenters written in RxJava Unit Testing and TDD with JUnit, Robolectric, Mockito, and Instrumentation testing REST/JSON Room and Realm for Android persistence Databases: MySQL, PostgreSQL, Intersystems Cache OODB, Oracle, MongoDB Build tools: Gradle & Maven Git Linux/UNIX experience (minimal shell-scripting experience) Wrote an article on developing a Clean architecture using MVVM & RxJava 2 Education: BSc Computing and Information Systems (University of London - First-class Honours June 2013) Coursera course: Creative Programming for Digital Media and Mobile Apps Coursera course: Programming Cloud Services for Android Handheld Systems
Updated on June 17, 2022Comments
-
blackpanther almost 2 years
The logic here is that if the ratings in the database are empty, then I want to get them from the API. I have the following code:
Observable.from(settingsRatingRepository.getRatingsFromDB()) .toList() .switchIfEmpty(settingsRatingRepository.getSettingsRatingModulesFromAPI()) .compose(schedulerProvider.getSchedulers()) .subscribe(ratingsList -> { view.loadRatingLevels(ratingsList, hideLocks); }, this::handleError);
The
getRatingsFromDB()
call returnsList<SettingRating>
, but the API call returnsObservable<List<SettingRating>>
.However, when I unit test this, when I pass an empty list from the database call, it does not execute the API call. Can someone pls help me in this matter. This is my unit test code:
when(mockSettingsRatingsRepository.getRatingsFromDB()).thenReturn(Collections.emptyList()); List<SettingsRating> settingsRatings = MockContentHelper.letRepositoryReturnSettingsRatingsFromApi(mockSettingsRatingsRepository); settingsParentalPresenter.onViewLoad(false); verify(mockView).loadRatingLevels(settingsRatings, false);