Skip to content

Instantly share code, notes, and snippets.

@abbas-oveissi
Last active February 29, 2020 02:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abbas-oveissi/170036ed900e5d148c113038669bc2ce to your computer and use it in GitHub Desktop.
Save abbas-oveissi/170036ed900e5d148c113038669bc2ce to your computer and use it in GitHub Desktop.
// rxjava-challenge-solution
// this example use RxJava 1.0
// Province class => data class Province(val id: Int ,val name:String, var cities:List<City>? = null)
class DataManager {
// solution
fun getProvincesAndCities(): Observable<List<Province>> {
return getProvinces()
.subscribeOn(Schedulers.io())
.flatMap { provinces -> Observable.from(provinces) }
.flatMap({ (id) -> getCityByProvinceId(id.toLong()) }, { province, cities ->
province.cities = cities
province
})
.toList()
.observeOn(AndroidSchedulers.mainThread())
}
// fake method
private fun getProvinces(): Observable<List<Province>> {
return Observable.just(listOf(Province(1, "tehran"), Province(2, "esfehan")))
}
// fake method
private fun getCityByProvinceId(provinceId: Long): Observable<List<City>> {
if (provinceId == 1L) {
return Observable.just(listOf(City(1, "tehran"), City(2, "rey")))
}
return Observable.just(listOf(City(3, "esfehan"), City(4, "shahin shahr")))
}
}
@seyedjafariy
Copy link

Thanks man, great job explaining it. I would like to point out that for this code to work out of the box there are a few more lines needed here they are:

class City(val id: Int, val name: String) data class Province(val id: Int, val name: String, val cities: List<City>)

line 9 did not work for me so here is the replacement:

Observable.fromIterable(provinces)

Province properties are immutable so we have to use copy instead of assignment (line 11):

val newProvince = province.copy(cities = cities)

in order to comply with the return type of getProvincesAndCities() func we need a .toObservable() operator after .toList(), because toList will return a Single not a Observable

Suggestion
there is a operator for line 9:
.flatMapIterable { provinces -> provinces }

gotcha
if we are actually observing something and there is no onComplete signal in the getProvinces() or getCities() the function getProvincesAndCities() wont actually return anything, that is because the toList() relies on onComplete signal to construct the list. so for example if you are watching your DB and trying to approach this problem this way you should watch out for that toList() operator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment