Last active
October 25, 2020 12:10
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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