Reputation: 826
In order to build my repository, I am retrieving 2 streams of data from Local Database and from remote API. I am trying to access the remote stream only if the mQuakesLocalDataSource
has no items by using the concat
operator as shown in many examples.
@NonNull
@Override
public Single<List<Quake>> getQuakes(){
return Single.concat(mQuakesLocalDataSource.getQuakes(),
mQuakesRemoteDataSource.getQuakes())
.first(dummyList);
}
The issue I am facing is that mQuakesRemoteDataSource
never returns a stream while mQuakesLocalDataSource
is empty, therefore I am not having any data result. I have tested mQuakesRemoteDataSource
in isolation and without the concat
operator it seems to be retrieving its appropriate stream.
Why is this happening?
mQuakesLocalDataSource
is based on Room and so therefore it should emit its stream and then complete, so it's not possible that the local source would emit a never-ending stream like SQLbrite
does.
I have tried variations of this operator like concatArray
and the result was the same, no data is being retrieved whatsoever.
An interesting note would be the fact that while debugging, I noticed that both mQuakesLocalDataSource
and mQuakesRemoteDataSource
get
methods are triggered when passed into concat
operator, before reaching the first()
line. Shouldn't concat
evaluate sources one by one (and filter the current one) in the presence of first
operator?
I have also tried adding a filter with a Predicate
in order to cache data into the Local Data Source, as below:
@NonNull
@Override
public Single<List<Quake>> getQuakes() {
return Single.concat(mQuakesLocalDataSource.getQuakes(),
mQuakesRemoteDataSource.getQuakes()).filter(new Predicate<List<Quake>>() {
@Override
public boolean test(List<Quake> quakes) throws Exception {
boolean isValid = quakes != null && !quakes.isEmpty();
// save items to local data source
if (isValid) saveQuakes(quakes);
return isValid;
}
}).first(new ArrayList<>());
}
The result was the same, no data is being retrieved.
Upvotes: 0
Views: 224
Reputation: 69997
Returning an empty list in Single
doesn't make the Single
empty, thus first
will correctly stop at the first item, the empty list, never calling the remote source. You have to decide on the item via flatMap
whether or not to resume with the remote source instead of concat:
mQuakesLocalDataSource.getQuakes()
.flatMap(list -> {
if (list.isEmpty()) {
return mQuakesRemoteDataSource.getQuakes();
}
return Single.just(list);
})
Upvotes: 1