Search code examples
androidretrofitrx-javathemoviedb-api

How to make two Retrofit calls and combine results?


I've been looking around StackOverflow and other Android-related sites to try and get a grasp on this, but I'm still struggling.

I'm using Retrofit to make calls to an API as follows:

public interface TheMovieDbApi {

@GET("genre/{type}/list")
Observable<GenresReply<Genre>> getGenreList(@Path("type") String type);

}

The above example returns an Object (GenresReply) which contains a List of Genres.

I need to make this call twice - once for movies, once for TV - and combine the results. Having looked at other examples here, I've come up with the following:

    private void loadGenres() {
    List<Observable<?>> requests = new ArrayList<>();

    requests.add(api.getGenreList("movie"));
    requests.add(api.getGenreList("tv"));

    //Now what?
}

I'm lost on the next step. I've seen examples using Observable.concat(), .flatMap() and .zip() and then subscribing to the output, but I'm not familiar enough with RxJava to know what to do next.

TL;DR How do I make two API calls and extract the List of Genres from each response/the combined List of Genres?

Solution

Thanks to the comments from John and masp, here's what I've come up with:

    private void loadGenres() {
    Observable.zip(api.getGenreList(MOVIE_GENRES), api.getGenreList(SHOW_GENRES),
            new BiFunction<GenresReply<Genre>, GenresReply<Genre>, List<Genre>>() {
                @Override
                public List<Genre> apply(GenresReply<Genre> movieReply, GenresReply<Genre> showReply)
                        throws Exception {
                    List<Genre> genreList = new ArrayList<>();
                    genreList.addAll(movieReply.getGenres());
                    genreList.addAll(showReply.getGenres());

                    return genreList;
                }
            }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<List<Genre>>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {

                }

                @Override
                public void onNext(@NonNull List<Genre> genres) {
                    DatabaseUtils.insertGenres(genres, ListActivity.this);
                }

                @Override
                public void onError(@NonNull Throwable e) {
                    mSharedPreferences.edit().putBoolean(FIRST_RUN, true).apply();
                }

                @Override
                public void onComplete() {

                }
            });
}

Solution

  • You should be able to do something like:

        Observable.zip(api.getGenreList("movie", api.getGenreList("tv", (movieInfo, tvInfo) -> Pair.create(movieInfo, tvInfo)).subscribe(movieTvPair -> {
    
        })