6

What I want to achieve is:

  • monitor preferences for a certain change
  • when a change is detected, start new network call using the new value
  • transform result
  • display result in UI

I know when the change happens, now I presume I need to call onNext on a Subject. This should then trigger a Rx chain, and in the end I can update the UI.

mViewPeriodSubject = PublishSubject.create();

mAdapterObservable =
    mViewPeriodSubject
        .flatMap(period -> MyRetrofitAPI.getService().fetchData(period)) // this might fail
        .flatMap(Observable::from)
        .map(MyItem::modifyItem)
        .toList()
        .map(obj -> new MyAdapter(obj));


mViewPeriodSubject.onNext("week"); // this one starts the chain
mViewPeriodSubject.onNext("year"); // this one does not

But in the case of the network call failing, the observable errors, and calling onNext() does not result in another network call.

So my question is, how should I handle this? How can I keep the Observable intact so I can just throw another value at it? I can imagine for example a simple retry button that just wants to ignore the fact that an error occurred.

xorgate
  • 2,244
  • 1
  • 24
  • 36
  • Read [this](https://github.com/ReactiveX/RxJava/wiki/Error-Handling), i'm guessing solution 3 or 4 applies (swallow the error and restart), using one of the [error handling operators](https://github.com/ReactiveX/RxJava/wiki/Error-Handling-Operators) might help, namely [retry or retryWhen](http://reactivex.io/documentation/operators/retry.html). – Dorus Jul 06 '15 at 13:13
  • There are also a few complete examples for `retryWhen` here on SO. – david.mihola Jul 06 '15 at 15:37
  • @david.mihola Like this https://stackoverflow.com/questions/18978523/write-an-rx-retryafter-extension-method (wrong language thou, that's C#). – Dorus Jul 06 '15 at 22:32

1 Answers1

7

You don't have to deal error with your mViewPeriodSubject but instead, deal with errors on your retrofit Observable. This retrofit Observable won't resume, but at least, it won't affect your "main" Observable.

mAdapterObservable =
mViewPeriodSubject
    .flatMap(period -> MyRetrofitAPI.getService().fetchData(period).onErrorResumeNext(e -> Observable.empty()) // this might fail
    .flatMap(Observable::from)
    .map(MyItem::modifyItem)
    .toList()
    .map(obj -> new MyAdapter(obj));
dwursteisen
  • 11,435
  • 2
  • 39
  • 36