Retrofit y RxJava: ¿cómo combinar dos solicitudes y obtener acceso a ambos resultados?

Necesito hacer dos solicitudes de servicios y combinar los resultados:

ServiceA () => [{"id":1,"name":"title"},{"id":1,"name":"title"}]

ServiceB ( id ) => {"field":"value","field1":"value"}

Actualmente, he logrado combinar los resultados, pero necesito pasar el id como parámetro al ServiceB y obtener acceso al primer resultado.

Lo que intenté hasta ahora:

  Retrofit repo = new Retrofit.Builder() .baseUrl("https://api.themoviedb.org/3/genre/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); Observable Genres = repo .create(services.class) .getAllGeneros("movie","list","da0d692f7f62a1dc687580f79dc1e6a0") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()); Observable Movies = repo .create(services.class) .getAllMovies("28","movies","da0d692f7f62a1dc687580f79dc1e6a0",12) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()); Observable combined = Observable.zip(Genres, Movies, new Func2() { @Override public CollectionsMovies call(GenerosResponse generosResponse, ResponseMovies responseMovies) { return new CollectionsMovies(generosResponse, responseMovies); } }); combined. subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(...); 

Editar

Solución según la respuesta de @Maxim Ostrovidov:

  private Observable makeRequestToServiceA() { return service.getAllGeneros("movie","list","da0d692f7f62a1dc687580f79dc1e6a0"); //some network call } private Observable makeRequestToServiceB(Genre genre) { return service.getAllMovies(genre.getId(),"movies","da0d692f7f62a1dc687580f79dc1e6a0","created_at.asc"); //some network call based on response from ServiceA } void doTheJob() { makeRequestToServiceA() .flatMap(userResponse -> Observable.just(userResponse.getGenres())) //get list from response .flatMapIterable(baseDatas -> baseDatas) .flatMap(new Func1<Genre, Observable>() { @Override public Observable call(Genre genre) { return makeRequestToServiceB(genre); } }, new Func2() { @Override public CollectionsMovies call(Genre genre, ResponseMovies responseMovies) { return new CollectionsMovies(genre,responseMovies); } }). subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(....); } 

Según tengo entendido, debe realizar una solicitud en función del resultado de otra solicitud y combinar ambos resultados. Para ello, puede utilizar esta variante de operador flatMap : Observable.flatMap (Func1 collectionSelector, Func2 resultSelector)

Devuelve un Observable que emite los resultados de una función específica al par de valores emitidos por la fuente Observable y una colección especificada Observable. enter image description here

Ejemplo simple para indicarle cómo reescribir su código:

 private Observable makeRequestToServiceA() { return Observable.just("serviceA response"); //some network call } private Observable makeRequestToServiceB(String serviceAResponse) { return Observable.just("serviceB response"); //some network call based on response from ServiceA } private void doTheJob() { makeRequestToServiceA() .flatMap(new Func1>() { @Override public Observable< ? extends String> call(String responseFromServiceA) { //make second request based on response from ServiceA return makeRequestToServiceB(responseFromServiceA); } }, new Func2>() { @Override public Observable call(String responseFromServiceA, String responseFromServiceB) { //combine results return Observable.just("here is combined result!"); } }) //apply schedulers, subscribe etc } 

Usando lambdas:

 private void doTheJob() { makeRequestToServiceA() .flatMap(responseFromServiceA -> makeRequestToServiceB(responseFromServiceA), (responseFromServiceA, responseFromServiceB) -> Observable.just("here is combined result!")) //... } 

El operador que está buscando es flatMap()

 serviceA.getAllGeneros("movie","list","da0d692f7f62a1dc687580f79dc1e6a0") .flatMap(genres -> serviceB.getAllMovies(genres.getId() ......))