thanhbinh84
thanhbinh84

Reputation: 18454

Rxjava with retrofit - zip() - how to bypass an error response

I am trying requesting 3 services at the same time and show the result when they are all competed. Everything is okay until one of requests is failed.

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    testZip();
}

private void testZip() {
    Retrofit repo = new Retrofit.Builder()
            .baseUrl("https://api.github.com")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    Observable<JsonObject> userObservable = repo
            .create(GitHubUser.class)
//                .getUser("username")
                .getUser("fakeUser_fakeUser")
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread());

    Observable<JsonArray> eventsObservable = repo
            .create(GitHubEvents.class)
            .listEvents("username")
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread());

    Observable<UserAndEvents> combined = Observable.zip(userObservable, eventsObservable, new Func2<JsonObject, JsonArray, UserAndEvents>() {
        @Override
        public UserAndEvents call(JsonObject jsonObject, JsonArray jsonElements) {
            return new UserAndEvents(jsonObject, jsonElements);
        }
    }).onErrorResumeNext(Observable.<UserAndEvents>empty());

    combined.subscribe(new Subscriber<UserAndEvents>() {
        @Override
        public void onCompleted() {
            Log.wtf("TAG", "onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            Log.wtf("TAG", "onError");
            Log.wtf("TAG", e.toString());
        }

        @Override
        public void onNext(UserAndEvents o) {
            Log.wtf("TAG", "onNext");
            Log.wtf("Username", o.user.get("name").toString());
            Log.wtf("First event", o.events.get(0).getAsJsonObject().get("type").toString());
        }
    });
}



public interface GitHubUser {
    @GET("users/{user}")
    Observable<JsonObject> getUser(@Path("user") String user);
}

public interface GitHubEvents {
    @GET("users/{user}/events")
    Observable<JsonArray> listEvents(@Path("user") String user);
}

public class UserAndEvents {
    public UserAndEvents(JsonObject user, JsonArray events) {
        this.events = events;
        this.user = user;
    }

    public JsonArray events;
    public JsonObject user;
}

}

What I want here is to get "events" data even if the user request is failed. I did try with onErrorReturn(), onErrorResumeNext(), onExceptionResumeNext() but they all go to onCompleted() without data. I intended to use mergeDelayError() but it requires the response data are the same that doesn't fit my app.

Upvotes: 2

Views: 603

Answers (1)

m.ostroverkhov
m.ostroverkhov

Reputation: 1960

Move onErrorResumeNext to userObservable, so zip will look like Observable<UserAndEvents> combined = Observable.zip(userObservable.onErrorResumeNext(Observable.just(new JsonObject()), eventsObservable,.... In case of error zipped result will contain empty JsonObject for User.

Upvotes: 3

Related Questions