Multiple requests with retrofit to combine results
Asked Answered
L

2

12

Im using retrofit (1.9) and trying to work out how i can call 2 apis and merge the results.

I guess the results should be merged when last api has finished returning a response...

How can i do this?

Udpate, as per Antons answer I have tried the following:

added to gradle:

  compile 'io.reactivex:rxjava:1.0.+'
    compile 'io.reactivex:rxandroid:0.23.+'

Api interface

 @GET("/maps/api/place/details/json")
    Observable<PlaceDetailResult1> getPlacesFrom1( @Query("key") String key,  @Query("placeid") String placeid);


@GET("api/places/{id}/ratings")
Observable<PlaceDetailResult2> getPlacesFrom2(@Path("id") String id);

In fragment

     IPlaces api = adapter.create(IPlaces.class); //endpoint1
     IPlaces api2 = adapter2.create(IPlaces.class); //endpoint2

    Observable.combineLatest(
            api.getPlacesFrom1("key", placeId),
            api2.getPlacesFrom2(placeId),
        new Func2<PlaceDetailResult1, PlaceDetailResult2, MergedReviews>() {
            @Override
            public MergedReviews call(PlaceDetailResult placeDetailResult1, PlaceDetailResult2 placeDetailResult2) {
                // processToMerge(  placeDetailResult1, placeDetailResult2)
                return mr;
            }

            })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<MergedReviews>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(MergedReviews mr) {

                    SetAdapter(mr.reviews);
                    SetPhotosAdapter(mr.photos);
                }
            });

One thing maybe worth noting, when I added RxJava to gradle i was getting some error, which went away after I did multiDexEnabled true in the gradle file

Lenoir answered 4/4, 2016 at 11:20 Comment(4)
Use RxJava with RetrofitMilklivered
@MD is RxJava the only way if using retrofit?Lenoir
@Lenoir for sure, you can create global counter and proceed results, when counter goes to zero (if you decrement it after successful response) but that 's painful, RxJava is much safer, cooler and easierDortch
@AntonShkurenko further code addedLenoir
D
5

You can use RxJava and combine results like this: Combining API calls with RX Java

Here is tutorial, how to use RxJava and Retrofit 1.9: http://randomdotnext.com/retrofit-rxjava/

Dortch answered 4/4, 2016 at 11:23 Comment(6)
Is retrofit 1.9 compatible with the method used in the SO link you have suggested?Lenoir
Did you ever check the link?Dortch
yeah, I checked both, I tried implementing as suggested in the SO post. and in debugging It just would not enter the onnext method...Lenoir
updated the question now, Ive added breakpoint in onnext, call, onerror etc, and it just seems to skip the lotLenoir
@Lenoir onNext doesn't get called?Dortch
@Lenoir huh :) nice to hearDortch
S
1

Using rxjava 2.X + Java 8 lambda :

Use Observables same as Ramkailash's answer.

Create Zip like this :

Observable<UserAndEvents> combined = Observable.zip(userObservable, eventsObservable, (jsonObject, jsonArray) -> new UserAndEvents(jsonObject, jsonArray));

Subscribe combined observable :

Disposable disposable = combined.subscribe(this::successUserAndEvents,this::throwableError);

private void successUserAndEvents(UserAndEvents o) {
      // You can access the results of the 
      // two observabes via the POJO now
}

private void throwableError(Throwable throwable){
      // handle throwable
}

Dispose disposable when not needed :

@Override
public void onStop() {
    super.onStop();
    if (disposable != null) disposable.dispose();
}
Sloop answered 3/11, 2017 at 9:36 Comment(1)
Any idea what to do when app goes background and comes to foregroundOverheat

© 2022 - 2024 — McMap. All rights reserved.