ARiF
ARiF

Reputation: 1089

How to call rest apis async and wait untill all calls are done in rx-android

In an activity i need to call 4 rest API. One API does not depends on another. But for a calculation I need data of all 4 APIs. So, I'm planning to call APIs asynchronous but wait until all API are done loading. I'm using RxAndroid with retrofit. I don't know how to achieve this using rx. I don't want to use a Boolean for each API call to track if it loaded or not. Is there any rx way?

For now, I synchronize all calls like below

Sample code:

fun getData() {
    val disposable = dataSource.getLivePayments()
                        .subscribeOn(schedulerProvider.io())
                        .observeOn(schedulerProvider.ui())
                        .subscribe(({ livePayments: List<Payment> ->
                            this.livePayments.clear()
                            this.livePayments.addAll(livePayments)

                            dataSource.getLiveRemittances()
                                .subscribeOn(schedulerProvider.io())
                                .observeOn(schedulerProvider.ui())
                                .subscribe(({ liveRemittances: List<Remittance> ->
                                    this.liveRemittances.clear()
                                    this.liveRemittances.addAll(liveRemittances)

                                    // similarly called dataSource.getLiveTimeSheets()
                                    // and dataSource.getArchiveTimeSheets()
                                    // synchronous
                                    // then call 
                                    calculateAmount()
                                }), ({ t -> this.parseError(t) }))
                        }), ({ t -> this.parseError(t) }))

    compositeDisposable.add(disposable)
}

fun calculateAmount() {
 val balance = if(liveRemittances.isNotEmpty()) {
    (sum(payment.amount) - sum(timesheet.amount)) * sum(liveRemittance.amount)
    } else {
        (sum(payment.amount) - sum(timesheet.amount))
    }
}

NB: In this procedure, if some API fails, it stop executing next API but i want it should call next API.

Upvotes: 2

Views: 1093

Answers (1)

Alberto S.
Alberto S.

Reputation: 7649

If all the API calls are independent you can use the zip operator:

Single.zip(single1, single2, ..., (result1, result2, ... -> (combine the results)})

If the have dependant results you can use flatMap

single1.flatMap(result -> (generate a new Single based on that result)})

Upvotes: 3

Related Questions