Skip to content

Instantly share code, notes, and snippets.

@MichalDanielDobrzanski
Last active October 25, 2020 12:10
Show Gist options
  • Save MichalDanielDobrzanski/95e5f889f7b2e53db1778a8a3e6bf450 to your computer and use it in GitHub Desktop.
Save MichalDanielDobrzanski/95e5f889f7b2e53db1778a8a3e6bf450 to your computer and use it in GitHub Desktop.
How to concat many network requests in RxJava and wait for their completion
package com.clarity.android.interview
import android.util.Log
import com.clarity.android.interview.network.DeliveryItem
import com.clarity.android.interview.network.NetworkApi
import com.clarity.android.interview.network.NetworkService
import com.clarity.android.interview.network.OrderResponse
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.annotations.Nullable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
class MainActivityViewModel {
interface UpdateListener {
fun onUpdate(state: ItemListViewState)
}
private var listener: UpdateListener? = null
private var disposable: Disposable? = null
private val networkApi: NetworkApi by lazy {
NetworkService().api
}
@Suppress("UNCHECKED_CAST")
fun fetch() {
disposable = networkApi.fetchOrdersObservable()
.switchMap { response ->
response.orders
val observables: MutableList<Observable<OrderResponse>> = mutableListOf()
response.orders.forEach { id ->
observables.add(
networkApi.fetchOrderByIdObservable(id)
.subscribeOn(Schedulers.io())
)
}
return@switchMap Observable.zip(observables) { sources: Array<Any> ->
sources.toList() as List<OrderResponse>
}
}
.map {
return@map it
.flatMap { el -> el.items }
.groupBy { el -> el.name }
.map { entry: Map.Entry<String, List<DeliveryItem>> ->
val count: Int = entry.value
.map { it.count }
.sumBy { it }
"${entry.key} $count"
}
// val counterMap: MutableMap<String, Int> = mutableMapOf()
// deliveryItemsList.forEach { item ->
// if (counterMap.containsKey(item.name)) {
// val currentCount = counterMap[item.name]!!
// counterMap[item.name] = currentCount + item.count
// } else {
// counterMap[item.name] = item.count
// }
// }
//
// return@map counterMap.entries.map { entry ->
// "${entry.key}:${entry.value}"
// }
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ result ->
listener?.onUpdate(
ItemListViewState(
DELIVERY_ITEM_TITLE,
result.map { ItemRow(it) }
))
},
{
Log.e("ERROR", it.toString())
}
)
}
fun destroy() {
disposable?.dispose()
}
fun setStateUpdateListener(@Nullable listener: UpdateListener?) {
this.listener = listener
}
companion object {
const val DELIVERY_ITEM_TITLE: String = "Delivery Items"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment