Reputation: 23
I have some kind of Result which I get from a server. I'm trying to build an observable sequence which will: 1. check that the result is successful (result.success()) 2. if it is, then get a string resource from the result (result.getResource()) and return an observable with that string 3. if it's not, then execute some failure handling code and return an empty observable
I can easily achieve that with a simple switchMap however then it contains side effects (the failure handling code) which I don't like because I want to keep the different operations separate if possible. Ideally I'd like to do the failure handling in a separate consumer but the problem is that I cannot pass the result of the .success() method without losing the Result object. Is there a way to achieve what I need?
Right now, my code looks something like this:
Observable<String> getResource() {
return getServerResult()
.switchMap(new Function<Result, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Result result) throws Exception {
if (result.success()) {
return Observable.just(result.getResource());
} else {
onFailure(result); // not happy about this side effect being here
return Observable.empty();
}
}
});
Upvotes: 1
Views: 125
Reputation: 11058
You can make your custom Exception
with a result stored in it, wrap it into stream error and return it in flatMap
if a result in not successful, call side effect method using doOnError
and convert it back to Observable
in ErrorResumeNext
:
class MyCustomException extends Exception {
Result result;
}
//do you really need switchMap?
.flatMap(result -> {
if (result.success()) {
return Observable.just(result.getResource());
} else {
return Observable.error(MyCustomException(result));
}
})
//do* operators is meant to call side effect methods without changing the stream
.doOnError(exception -> {
if(exception instanceof MyCustomException) {
Result result = ((MyCustomException) exception).getResult();
onFailure(result);
}
})
.onErrorResumeNext(exception -> {
if(exception instanceof MyCustomException) {
return Observable.empty();
} else {
return Observable.error(exception); //propagate error downstream
}
})
Upvotes: 2