4
votes

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?

1

1 Answers

0
votes

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()
        })
}