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
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.