Цепочка запроса на модификацию с использованием rxJava2 и заполнение результата в представлении реселлера - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь использовать API из thesportsdb для отображения lastmatch из конкретной лиги. В своем обзоре я хочу показать значок команды для каждой команды, но когда я запрашивал API Lastmatch, он не включал значок команды, только идентификатор каждой команды, и если я хочу показать значок, он требует от меня запроса команды профиль, который включает в себя URL для значка команды.

Поскольку я новичок в rxJava, я все еще знакомлюсь с ним. в некоторых сообщениях предлагается использовать flatmap, но новичку вроде меня сложно реализовать его.

это сервис по модернизации:

interface FootballRest {

@GET("eventspastleague.php")
fun getLastmatch(@Query("id") id:String) : Flowable<FootballMatch>

@GET("lookupteam.php")
fun getTeam(@Query("id") id:String) : Flowable<Teams>
}

Я использовал шаблон репозитория

class MatchRepositoryImpl(private val footballRest: FootballRest) : MatchRepository {
override fun getFootballMatch(id: String): Flowable<FootballMatch> = footballRest.getLastmatch(id)

override fun getTeams(id: String): Flowable<Teams> = 
footballRest.getTeam(id)
}

и это ведущий, который выполняет вызов и отправляет данные в представление:

class MainPresenter(val mView : MainContract.View, val matchRepositoryImpl: MatchRepositoryImpl) : MainContract.Presenter{

val compositeDisposable = CompositeDisposable()

val requestMatch = matchRepositoryImpl.getFootballMatch("4328")
val requestTeam = matchRepositoryImpl.getTeams()

override fun getFootballMatchData() {
    compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328")
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe{
                mView.displayFootballMatch(it.events)
            })
}

Пока я показываю только результат последнего матча, но я также хочу показать команду со значками в списке.

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Вместо использования оператора blockingGet, вероятно, вам проще использовать плоскую карту и вернуть все эти данные в виде единого потока.

Этого можно добиться, комбинируя оператор flatmap и zip . Это будет выглядеть примерно так: в MatchData хранятся данные FootballMatch, а также данные homeTeam и awayTeam.

data class MatchData(val footballMatch: FootballMatch, val homeTeam: Teams, val awayTeam: Teams)

Тогда для операции с плоской картой потребуется вызвать метод getTeams как для домашней, так и выездной команды, который затем можно будет объединить с данными footballMatch через zip-опратор.

override fun getFootballMatchData() {
    compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328")
            .subscribeOn(Schedulers.io())
            .flatMap { footballMatch ->
                Flowable.zip(
                        matchRepositoryImpl.getTeams(footballMatch.idHomeTeam),
                        matchRepositoryImpl.getTeams(footballMatch.idAwayTeam),
                        BiFunction { homeTeam: Teams, awayTeam: Teams ->
                            MatchData(
                                    footballMatch = footballMatch,
                                    homeTeam = homeTeam,
                                    awayTeam = awayTeam)
                        }
                )
            }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                mView.displayFootballMatch(it)
            })
}
0 голосов
/ 01 сентября 2018

Для этого можно использовать оператор map в сочетании с lastElement().blockingGet() для второго Observable, а затем вернуть Pair результатов. Простой пример может быть следующим:

@Test
public fun test1() {
    Observable.just(1)
            .map {
                // here 'it' variable is calculated already so it can be passed to the second observable
                val result = Observable.just(2).lastElement().blockingGet()
                 Pair<Int, Int>(it, result)
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { t -> System.out.println("First : " + t?.first + ", second : " + t?.second) }

    Thread.sleep(1000)
}

выход

1 2

Если ваш второй Observable зависит от результата первого, то просто используйте переменную it внутри оператора map и передайте его в любое место, где это необходимо. Таким образом, если использовать предыдущий пример, ваш код может быть преобразован в это:

override fun getFootballMatchData() {
    compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328").toObservable( 
            .map {
                // here 'it' variable is calculated already so it can be passed to the second observable
                val next = matchRepositoryImpl.getTeams(it).toObservable().lastElement().blockingGet()
                Pair<Int, Int>(it, next)
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe{ t ->
                mView.displayFootballMatch(t.first)
                mView.displayBadgeTeam(t.second)
            })
}
...