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, me las he arreglado para combinar los resultados, pero tengo que pasar id como un parámetro para la ServiceB y obtener el primer resultado.

Lo que he probado hasta ahora:

   Retrofit repo = new Retrofit.Builder()
                .baseUrl("https://api.themoviedb.org/3/genre/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

        Observable<GenerosResponse> Genres  = repo
                .create(services.class)
                .getAllGeneros("movie","list","da0d692f7f62a1dc687580f79dc1e6a0")
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread());

        Observable<ResponseMovies> Movies = repo
                .create(services.class)
                .getAllMovies("28","movies","da0d692f7f62a1dc687580f79dc1e6a0",12)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread());

        Observable<CollectionsMovies> combined = Observable.zip(Genres, Movies, new Func2<GenerosResponse, ResponseMovies, CollectionsMovies>() {
            @Override
            public CollectionsMovies call(GenerosResponse generosResponse, ResponseMovies responseMovies) {
                return new CollectionsMovies(generosResponse, responseMovies);
            }
        });

        combined.
                subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(...);

Editar

Solución de acuerdo con @Maxim Ostrovidov la respuesta:

 private Observable<GenerosResponse> makeRequestToServiceA() {
        return  service.getAllGeneros("movie","list","da0d692f7f62a1dc687580f79dc1e6a0"); //some network call
    }

    private Observable<ResponseMovies> 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<? extends ResponseMovies>>() {

                    @Override
                    public Observable<? extends ResponseMovies> call(Genre genre) {
                        return makeRequestToServiceB(genre);
                    }
                }, new Func2<Genre, ResponseMovies, CollectionsMovies>() {

                    @Override
                    public CollectionsMovies call(Genre genre, ResponseMovies responseMovies) {
                        return new CollectionsMovies(genre,responseMovies);
                    }
                }).
                subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(....);
    }
Usted necesita llamar a ServiceB con los parámetros del resultado de la llamada a ServiceA?
sí exactamente @LordRaydenMK

OriginalEl autor David Hackro | 2017-01-22

2 Comentarios

  1. 27

    Como yo lo entiendo – que usted necesita para hacer una petición basada en el resultado de la otra solicitud y combinar ambos resultados. Para esto se puede utilizar este flatMap operador variante: Observable.flatMap(Func1 collectionSelector, Func2 resultSelector)

    Devuelve un Observable que emite los resultados de una función especificada a la par de los valores emitidos por la fuente Observables y una colección especificada Observable.Actualización y RxJava: Cómo combinar dos solicitudes y obtener acceso a ambos resultados?

    Ejemplo sencillo de señalar cómo reescribir el código:

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

    El uso de expresiones lambda:

    private void doTheJob() {
        makeRequestToServiceA()
                .flatMap(responseFromServiceA -> makeRequestToServiceB(responseFromServiceA),
                        (responseFromServiceA, responseFromServiceB) -> Observable.just("here is combined result!"))
                //...
    }
    pero si mi servicio de devolución de objetos de la lista y mi necesidad de un servicio de identificación de cada objeto?
    Por favor proporcione el código de getAllGeneros y getAllMovies métodos.
    He actualizado a la pregunta con más información
    No puedo entender cuál es el problema que están tratando de resolver con su código. Puede usted por favor proporcione una explicación común, por ejemplo, «estoy tratando de mostrar las películas por géneros, pasando género id…»
    Para conseguir que todo el código debe ser reescrito, así que por favor tome el tiempo para analizar mi ejemplo.

    OriginalEl autor Maksim Ostrovidov

  2. 2

    El operador que se busca es la flatMap()

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

    OriginalEl autor LordRaydenMK

Dejar respuesta

Please enter your comment!
Please enter your name here