sorry_I_wont
sorry_I_wont

Reputation: 658

RxJava: How to transform a Single<Response> to Single<List<Item>>

Let's say I have an Android app with the following Repository class to fetch objects from API:

override fun fetchOrderById(orderId: Long): Single<List<ItemRow>> {
    return api.fetchOrderByIdObservable(orderId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .map { orderResponse ->
                orderResponse.items.map { deliveryItem ->
                    deliveryItem.asItemRow()
                }
            }
}

override fun fetchOrders(): Single<OrdersResponse> {
    return api.fetchOrdersObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
}

override fun fetchAllOrders(): Single<List<ItemRow>> {
     // TODO
}

With the following data class:

class OrdersResponse(@SerializedName("orders") val orders: List<Long>)
class OrderResponse(@SerializedName("items") val items: List<DeliveryItem>)

Right now, I can use fetchOrderById to get all delivery items (ItemRow) for a certain orderId as a domain object in my app to show in a list. How can I use fetchOrders, which returns a list of orderIds to get all delivery items for all orders? Which operators would be useful here? I played around with FlatMap, but could not get it to work. Link to articles would be ++ too. Thanks!

Upvotes: 1

Views: 1329

Answers (2)

sorry_I_wont
sorry_I_wont

Reputation: 658

This worked eventually:

    public fun fetchAllItems(): Observable<List<ItemRow>> {
    return networkService.api.fetchOrdersObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap { orderResponse ->  Observable.just(orderResponse.orders) }
            .flatMapIterable { id -> id }
            .flatMap { id -> fetchOrderById(id) }
            .flatMapIterable { itemRow -> itemRow }
            .toList()
}

Upvotes: 0

borichellow
borichellow

Reputation: 1001

operators you need: switchMap(), flatMap(), fromArray(), toList(), map() it's gonna be something like this:

fun fetchAllOrders(): Observable<List<ItemRow>> {
    return fetchOrders()
        .toObservable()
        .switchMap { ordersResponse ->
            Observable.fromIterable(ordersResponse.orders)
                .flatMap {orderId -> fetchOrderById(orderId).toObservable() }
                .toList()
                .toObservable()
        }
        .map { list -> list.flatten() }
    }

Upvotes: 1

Related Questions