Skip to content Skip to sidebar Skip to footer

Retrofit + Rxjava: How To Implement Iterable N Requests?

I have a problem to implement following problem: I'm making a request that fetches all active leagues. Then, for each of them I need to make another request to grab the matches. I

Solution 1:

Try this code:

leaguesApi              // your REST adapter from retrofit
                .getLeagues(true)    // fetch leagues
                .flatMapIterable(leagues -> leagues)    //Transform from ArrayList<Liague> to Observable<Liague>
                .flatMap(l -> leagueApi.getMatchesPlayed(l.getId(), true))
                .subscribe(
                        (match) -> {/*This is onNext*/},
                        t -> t.printStackTrace(), //onError
                        () -> {/*onComplete*/}
                );

UPDATE:

Without lambdas:

leaguesApi              // your REST adapter from retrofit
                .getLeagues(true)    // fetch leagues
                .flatMapIterable(newFunc1<ArrayList<League>, Iterable<?>>() {
                    @OverridepublicIterable<?> call(ArrayList<League> leagues) {
                        return leagues;
                    }
                })    //Transform from ArrayList<Liague> to Observable<Liague>
                .flatMap(newFunc1<League, Observable<Match>>() {
                    @OverridepublicObservable<Match> call(League l) {
                        return leagueApi.getMatchesPlayed(l.getId(), true);
                    }
                })
                .subscribe(
                        newAction1<Match>() {
                            @Overridepublicvoidcall(Match match) {
                                //onNext
                            }
                        },
                        newAction1<Throwable>() {
                            @Overridepublicvoidcall(Throwable throwable) {
                                //onError
                            }
                        },
                        newAction0() {
                            @Overridepublicvoidcall() {
                                //onComplete
                            }
                        }
                );

Solution 2:

I'd change that API so it reads like this otherwise you lose a lot of the flexibility of streams:

publicinterfaceLeaguesApi
{
    @GET("/api/get-leagues")
    Observable<League> getLeagues(@Query("active_only") boolean activeOnly);
}

publicinterfaceLeagueApi
{
    @GET("/api/get-league-fixtures/{leagueId}")
    Observable<Match> getMatchesPlayed(@Path("leagueId") int leagueId, @Query("played") boolean played);
}

Can you do that?

If not then to get Observable<T> from Observable<ArrayList<T>> you do:

observable.flatMapIterable(
    new Func1<ArrayList<T>, ArrayList<T>>() {
        @OverridepublicArrayList<T> call(ArrayList<T> list) {
            return list;
        }
    });

much nicer to just say observable.flatMapIterable(x -> x) of course.

To get all played matches for all active leagues just do this:

Observable<League> leagues= getLeagues(true);
Observable<Match>matches=
    leagues.flatMap( league -> getMatchesPlayed(league.leagueId, true));

or without lambdas (I wish you hadn't asked for that)

Observable<Match> matches = leagues.flatMap(
    new Func1<League, Observable<Match>> () {
        @OverridepublicObservable<Match> call(League league) {
            return getMatchesPlayed(league.leagueId, true);
        }
    });

Post a Comment for "Retrofit + Rxjava: How To Implement Iterable N Requests?"