Reputation: 6996
I have two observable, one gets list from SharedPreferences
and the other one gets it from api with retrofit(Ver 1.9.0). I use mergeDelayError
to let both observables emit their items even after any error.
Observable.mergeDelayError(Observable.just(instance.getListFromSharedPrefs()), instance.getListFromApi())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Observer<List<Item>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.d("ItemList", "Error: " + e.toString());
}
@Override
public void onNext(List<Item> Items) {
Log.d("ItemList", "ItemsFetched:" + Items.toString());
if (mAdapter != null) {
mAdapter.setItems(Items);
}
}
});
But when there is an error with retrofit api call(i.e. No internet connection), the whole process is completed after onError
and it can not get the list from SharedPreferences
.
This is the log when app first starts:
12-30 15:49:23.044 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:49:23.189 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:49:23.409 12197-12197/com.me.android D/itemList: Error: retrofit.RetrofitError
But when i close the app and reopen it everything works fine:
12-30 15:51:27.396 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.426 12197-12197/com.me.android D/itemList: itemsFetched:[com.me.android.model.entity.item.item@676ffe9]
12-30 15:51:27.438 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.618 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.700 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.772 12197-12197/com.me.android D/itemList: Error: retrofit.RetrofitError
Upvotes: 2
Views: 556
Reputation: 70017
The problem is likely the observeOn
which let's onError cut ahead of any value, no matter of the mergeDelayError
delaying the error after the value.
There is a PR waiting for approval that lets observeOn
also delay errors, but for now, you can apply materialize
before observeOn
and dematerialize
just after it.
Edit Example:
Observable.mergeDelayError(
Observable.just(
instance.getListFromSharedPrefs()), instance.getListFromApi())
.materialize()
.observeOn(AndroidSchedulers.mainThread())
.dematerialize()
.subscribeOn(Schedulers.newThread())
.subscribe(...);
Upvotes: 4
Reputation: 13321
mergeDelayError
does not remove the error, it just delays it unit the other observables finish emitting items.
You might wanna try using onErrorReturn
eg:
instance.getListFromSharedPrefs().mergeWith(instance.getListFromApi().onErrorReturn(Observable.empty())
to ignore a network in the API call.
Upvotes: 2