How to combine several API calls to create single response object using RxJava

rxjava multiple api calls
rxjava chain api calls
rxjava sequential api call
rxjava single example
rxjava zip list of observables
rxjava zip parallel
rxjava post request
rxjava api call

I'm building an application which consists of two API calls. I'm still learning RxJava and I'm not sure how to combine properly the two API calls

  1. The first API call is used to retrieve items in form of a list
  2. The second API call is used to retrieve item image using the item name that I got from the first call.

I need to show all the items with their images. Those are my API calls using retrofit

@GET("items/list")
fun getItems(): Observable<ItemResult>

@GET("item/{name}/images")
fun getItemDetails(@Path("name") name: String): Observable<ItemDetails>

This is the code that wrote with RxJava:

    fun getItemsData(): Observable<ArrayList<ItemDetails>> {

    val data = ArrayList<ItemDetails>()
getItems().flatMap { itemResponse -> Observable.just(itemResponse.message) } //this will give me a list with item names
        .flatMapIterable { data -> data }//iterating over the list and for every item...
        .map { itemName ->//calling to get the item image
            getItemDetails(itemName).map { imageData ->
                val itemImage = imageData.message
                data.add(ItemData(itemName, itemImage))//from this point on I'm lost, I'm not sure if it's the right thing to add here the data
            }.subscribeOn(Schedulers.io())
        }.subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())

    return Observable.create(data)// not sure how to create an Observable from the data
}   

You don't really need this...

val data = ArrayList<ItemDetails>()

flatMap is not the right operator here:

flatMap { itemResponse -> Observable.just(itemResponse.message) }

you can simplify this by using map instead (the function itemResponse -> itemResponse.message operates on the inner value only).

map { itemResponse -> itemResponse.message }

Next:

.flatMapIterable { data -> data } // here we have Observable<Message>
.flatMap { itemName ->
     getItemDetails(itemName).map { imageData ->
        ItemData(itemName, imageData)
     }
 } // Observable<ItemData>
.toList() // Single<List<ItemData>> -> you can use toObservable to get an Observable<List<ItemData>>

You can use toList() instead of manually creating and populating the ArrayList, it simplifies things.

Combining Response of 2 API call by RxJava, You can use RxJava's zip operator to combine result of two api calls. You will also need to create a DTO object to represent the combination of both the API calls. The response format for JSON batch requests is similar to the request format. The following are the key differences: The property in the main JSON object is named responses as opposed to requests. Individual responses might appear in a different order than the requests. Rather than method and url, individual responses have a status property.


You need to map the flat mapped stream to return the desired type -

getItems()
.flatMap(item -> getItemDetails(item)
                 .map(itemDetail -> ItemData(item, itemDetail.image))
.subscribe(itemData -> // your desired type containing the original item and image);

How to make complex requests simple with RxJava in Kotlin, Using the zip operator to combine the results of multiple requests. First we implement Those have the same types as the responses. The thing we Using the Kotlin Collections API to create our DetailsModel. I think one of In this example we transform the Answer objects to AnswerViewModel objects. TL;DR: All other application considerations aside, performing a single call would be faster than performing multiple calls. Running the calls asynchronously may cut down the overall time needed to complete a given operation from the perspective of your user (which might well be all you need), but in aggregate, the time taken would still be longer for multiple calls.


You're not subscribing to the inner-stream inside the map. Try this:

val data = ArrayList<ItemDetails>()
    getItems().flatMap { itemResponse -> Observable.just(itemResponse.message) } //this will give me a list with item names
            .flatMapIterable { data -> data }//iterating over the list and for every item...
            .flatmap(itemName -> getItemDetails(itemName).subscribeOn(Schedulers.io())
            .map(itemDetail -> {//add to the list)})
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())

    return Observable.fromIterable(data);

Android, RxJava and Retrofit: Wait for multiple network calls to finish , Let's first define our Retrofit object to access Github's API, then setup two observables for the two network requests above: addConverterFactory(​GsonConverterFactory.create()) Lately we use RxJava's zip method to combine our two Observables and It's just a simple POJO to combine the two objects:. returns a Single that emits the result of a function applied to the item emitted by the source Single: merge: Single: converts a Single that emits a second Single into a Single that emits the item emitted by the second Single: merge and mergeWith: Observable: merges the items emitted by multiple Singles as Observable emissions: observeOn: Single: instructs the Single to call the subscriber methods on a particular Scheduler: onErrorReturn: Single


If you really wish to return an Observable<ArrayList<ItemDetails>>, may be you could use reduce?

Something like that:

fun getItemsData(): Observable<ArrayList<ItemDetails>> {
   return
     getItems().flatMap { itemResponse -> Observable.just(itemResponse.message) }
               .flatMapIterable { data -> data }
               .flatMap { itemName -> getItemDetails(itemName)  }.subscribeOn(Schedulers.io())
               .map { imageData -> ItemData(itemName, imageData.message) } }
               .reduce(ArrayList<ItemDetails>(), (list, item) -> list.add(item))
               .toObservable()   
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
}

I am not sure about the right syntax of reduce in Kotlin...

Chaining different network queries with RxJava, This is because Retrofit combines perfectly well with RxJava, thanks in We're editing the file that lets us list calls on the Github API. Each one will return an Observable so that our controllers setText(response); } private void we're creating a second stream, which will combine the running of the two  Update employee(s) records from different entities using ODATA $batch API in SAP SuccessFactors


Combining Observables in RxJava, In this quick tutorial, we'll discuss different ways of combining pattern wherein an object called an Observer, subscribes to items emitted by an Observable. can call both at the same time and subscribe to the combined streams. can combine multiple Observables in RxJava and the different use-cases  Using the zip operator to combine the results of multiple requests First we implement the combination of the 3 requests. We will use the zip operator from RxJava. The ReactiveX documentation says


SmallRye Mutiny, Mutiny is designed after having experienced many issues with other Reactive single or multi items streams - Mutiny provides 2 types: Uni and Multi Joining asynchronous calls, i.e. being notified when multiple actions complete, is a To create a Uni from RxJava 2 objects, use the following methods:. A typical pattern we run into with single page apps is to gather up data from multiple API endpoints and then display the gathered data to the user. Fetching numerous asynchronous requests and managing them can be tricky but with the Angular’s Http service and a little help from the included RxJS library, it can be accomplished in just a few


Asynchronous JavaScript: Using RxJS Observables with REST APIs , In the rxjs directory, create a file called rx-http-request.js and insert the a lot of information in the JSON object that represents the HTTP response: The code above makes multiple API calls to compute average review one value, then the Observable returned by combineLatest emits the first set of data. the unfortunate reality is that increasingly open source repositories are populated not by code carrying one of the aforementioned types of licenses, but no license at all. Thinking of my own