Retrofit + rxJava: how to implement iterable N requests?

為{幸葍}努か 提交于 2019-12-24 15:56:40

问题


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 think it's possible to implement the solution using flatMapIterable, but don't know how.

For now I have following retrofit interfaces:

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

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

Please advise how to iterate through all leagues in order to perform getMatchesPlayed for each of them. Best would be without lambda expressions, since I'm not using them in my project.


回答1:


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

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

public interface LeagueApi
{
    @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>>() {
        @Override
        public ArrayList<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>> () {
        @Override
        public Observable<Match> call(League league) {
            return getMatchesPlayed(league.leagueId, true);
        }
    });



回答2:


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(new Func1<ArrayList<League>, Iterable<?>>() {
                    @Override
                    public Iterable<?> call(ArrayList<League> leagues) {
                        return leagues;
                    }
                })    //Transform from ArrayList<Liague> to Observable<Liague>
                .flatMap(new Func1<League, Observable<Match>>() {
                    @Override
                    public Observable<Match> call(League l) {
                        return leagueApi.getMatchesPlayed(l.getId(), true);
                    }
                })
                .subscribe(
                        new Action1<Match>() {
                            @Override
                            public void call(Match match) {
                                //onNext
                            }
                        },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                //onError
                            }
                        },
                        new Action0() {
                            @Override
                            public void call() {
                                //onComplete
                            }
                        }
                );


来源:https://stackoverflow.com/questions/31579789/retrofit-rxjava-how-to-implement-iterable-n-requests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!