I am new to RxJava. I am struggling with chaining multiple API calls. The class structures are as follows:
Location(location_id, location_name)
Hub(hub_id, hub_name, location_id)
Room(device_id, room_id, room_name)
LocationList is defined as
LocationList: List<Location>
The requirement is
forEach location in LocationList{ location->
getHubs(location.location_id) //returns Single<List<Hub>>
forEach hub in hubList{ hub->
getRoom(hub.hub_id) // returns Single<Room>
store HubItem(
location.location_id,
location.location_name,
hub.hub_id,
hub.hub_name,
room_name
) in a list
}
}
output list
The final output is a List<HubItem>
.How to achieve the above through RxJava?
CodePudding user response:
You would need to use few RxJava operators in order to accomplish it, you can nest them in order to keep track of the values that you will need in order to create the HubItem
val hubItems: Single<List<HubItem>> = Observable.fromIterable(locations)
.flatMap { location ->
getHubs(location.location_id)
.flattenAsObservable { it }
.flatMapSingle { hub ->
getRoom(hub.hub_id)
.flatMap { room ->
Single.just(
HubItem(
location_name = location.location_name,
locationId = location.location_id,
hub_id = hub.hub_id,
hub_name = hub.hub_name,
room_name = room.room_name
)
)
}
}
}.toList()
This is one way to accomplish it. First, you need create Observable stream from your list, Observable.fromIterable()
will create a stream of items, then in the first flatMap you will have access to your location and you can return your hubs. This is returning a Single
containing a normal list so you need to transform it to a stream of items. You can accomplish it i.e by flattenAsObservable()
operator which will emit your hub list as Observable sequence.
Next, you can use flatMapSingle()
, where you can return your Room. Having access to your Room you now have all the necessary data to create your HubItem, you will emit it as a single using Single.just(...)
.
In the end, you can use toList()
operator which will collect all emitted items into Single<List<HubItem>>
. Of course there are multiple ways to accomplish it, but this should reflect the example and types that you provided in pseudo-code. In order to get the normal List you need to subscribe to the Single, but I assume the subscription part is not a problem here.