Search code examples
javaandroidrx-javarx-androidrx-binding

How to call a non-rx network call that depends on an rx network call


I have a network call that returns an Observable, and I have another network call that it is not rx that depends on the first Observable and I need to somehow convert it all with Rx.

Observable<Response> responseObservable = apiclient.executeRequest(request);

After executing I need to do another http call that does not return an Observable:

responseObservable.map(response - > execute the no rx network call using the response.id) 

noRxClient.getInformation(response.id, new Action1<Information>() {
    @Override
    public void call(Information information) {
        //Need to return information with page response
    }
});

After then I need to call this method to render the response

renderResponse(response, information);

How can I connect the non-rx call with the rx and then call render response all with RxJava?


Solution

  • You can wrap your async non-rx calls into Observable using Observable.fromEmitter (RxJava1) or Observable.create (RxJava2) and Observable.fromCallable (for non-async calls):

    private Observable<Information> wrapGetInformation(String responseId) {
        return Observable.create(emitter -> {
            noRxClient.getInformation(responseId, new Action1<Information>() {
                @Override
                public void call(Information information) {
                    emitter.onNext(information);
                    emitter.onComplete();
                    //also wrap exceptions into emitter.onError(Throwable)
                }
            });
        });
    }
    
    private Observalbe<RenderedResponse> wrapRenderResponse(Response response, Information information) {
        return Observable.fromCallable(() -> {
            return renderResponse(response, information);
            //exceptions automatically wrapped
        });
    }
    

    And combine results using overloaded flatMap operator:

    apiclient.executeRequest(request)
        .flatMap(response -> wrapGetInformation(response.id), 
                (response, information) -> wrapRenderResponse(response, information))
        )
        //apply Schedulers
        .subscribe(...)