Solution 1 :
Try to use take(1) instead of toList(), but you should try to not save your results out of stream and do it inside.
EDIT this solution should work as you want:
private fun getData() {
appDatabase.tierListDao().getChampionOfTier()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.switchMap{ champions ->
val tierChamps = champions.map {
TierChampionAndCounterPicks().apply {
tierAndChampion = it
}
}
Observable.fromIterable(tierChamps).switchMap { tierChamp ->
appDatabase.counterPicksDao()
.getCounterPicksWithChampionId(tierChamp.championTable!!.id!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map { counterPicksTableList ->
tierChamp.apply {
counterPicks = counterPicksTableList
}
}
}
}
.toList()
.subscribe({ tierList ->
tierListAdapter = TierListAdapter(context!!, tierList)
tierListRv.adapter = tierListAdapter
}, {
it.printStackTrace()
})
}
Problem :
I have a request that I get championList from room database. I just wanna make another request by using championId for every item. So I used Observable.fromIterable(). I have two requests in total and both of them return observable. I will explain my code below:
private fun getData() {
appDatabase.tierListDao().getChampionOfTier()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.concatMap {
Observable.fromIterable(it)
}
.doOnNext {
tierListMap[it.championTable!!.id!!] = TierChampionAndCounterPicks().apply {
tierAndChampion = it
}
}
.flatMap { tierAndChampion ->
appDatabase.counterPicksDao()
.getCounterPicksWithChampionId(tierAndChampion.championTable!!.id!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
.map {
tierListMap[it.first().counterPicksTable?.low_level_champion_id]?.apply {
counterPicksTableList = it
}?.let { tier ->
tierList.add(tier)
}
tierList
}
.toList()
.subscribe({
tierListAdapter = TierListAdapter(context!!, tierList)
tierListRv.adapter = tierListAdapter
}, {
it.printStackTrace()
})
}
I am saving my first result into map with doOnNext. With flatMap, I am making my second request by using championId. I am also saving my second result into map with map() method. After that I wanna trigger subscribe method just once. But without toList() method, subscribe is triggered by the length of my list. With toList() method, subscribe is never triggered. How can I fix it?
Comments
Comment posted by Burcu TOPÇU
When I use take(1), just first item of my list appears on the screen. Without toList() and take(1), everytime subscribe is triggered, new item is added to list. So with take(1) just first item is added to list.
Comment posted by Burcu TOPÇU
Thank you for your edit, it makes my code shorter but again it does not trigger anything after toList(). It is so weird, I think we should write something to complete toList() process but I don’t know what to write. I mean it does not trigger anything after toList() because toList() process is not completed
Comment posted by Nikron
Maybe there is some error on stream. Try to add onError on getCounterPicksWithChampionId and see if everything is ok
Comment posted by Burcu TOPÇU
getCouterPicksWithChampionId works well, it does not enter onError() and it has my list items correctly. So if you have another idea to solve, I can try it also.
Comment posted by Nikron
@BurcuTOPÇU for more help i would need more details of your app maybe it is something wrong with getChampionOfTier() becouse i made my own small sample and everything was ok. Try to debug this place “counterPicks = counterPicksTableList” and look if it runs for every champion from getChampionOfTier().