0
votes

I have 2 calls from Retrofit which pulls images from 2 different Subreddits. I need assistance on how to use observables#zip() operator to get both the results in a single list. I appreciate it if anyone could help me with this.

Below is the Retrofit configuration:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.reddit.com/r/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

RedditAPI backendApi = retrofit.create(RedditAPI.class);

I am creating a list of observables to store the results of multiple calls:

List<Observable<?>> requests = new ArrayList<>();

requests.add((Observable<?>) backendApi.getpics());
requests.add((Observable<?>) backendApi.getearthporn());

I could not figure the proper usage of the Zip operator. Here's what I have:

Observable.zip(
        requests, 
        new Function<Object[], Object>() {
            @Override
            public Object apply(Object[] objects) throws Exception {                                            
                return new Object();
            }
        }).subscribe(new Consumer<Object>() {
                         @Override
                         public void accept(Object o) throws Exception {       
                            Log.d(TAG, "accept: "+o.toString());
                         }
                     }, new Consumer<Throwable>() {
                         @Override
                         public void accept(Throwable e) throws Exception {
                                Log.d(TAG, "accept: " + e.getLocalizedMessage());                            
                         }
                     }
        );
    }

I am creating a Reddit photos app. I was successful in calling each individual request, meaning my Retrofit interface is working. However, I can't figure out how to combine multiple requests using the zip operator. I get FATAL Exception: Main error when the code is run.

1

1 Answers

0
votes

In your apply function. You can cast the objects array to your model class types. Say your Retrofit interface looks like the following:

 @GET("some")
 Observable<SubredditBody> getPics();

 @GET("some\more")
 Observable<SubredditBody> getEarthPorn();

// I have no idea what your the actual rest endpoints are but I'm assuming you 
// already have this portion down.

You can loop through your result:

new Function<Object[], Object>() {
   @Override
   public Object apply(Object[] objects) throws Exception {                                            

        for (Object object : objects) {
             // Do something interesting here. This array has the result of your two API calls.
            if (object instanceOf SubredditBody) {
                SubredditBody body = (SubredditBody) object;
            }        
        }
        // Return your cool new object however you want. I didn't show how to 
        // instantiate this object but that's really up to you and your business
        // logic.
        return object;
    }
}

The second type you declared in this signature is the type you'll receive in your subscription like so:

new Function<Object[], YourCoolNewType>() {
    ...
}).subscribe(new Consumer<YourCoolNewType>() {
    @Override
    public void accept(YourCoolNewType o) throws Exception {
         // Do something here
    }
});