Упростите утверждение, используя rxkotlin - PullRequest
0 голосов
/ 06 января 2019

Я хотел попробовать RxJava с kotlin, чтобы упростить кодирование, поэтому я произвел это:

fun postAnswers() {
    disposable = getToken.execute().subscribe({ token ->
        questions.forEach { form ->
            val answers = form.answers?.filter { it.isChecked }?.map { it.answer_id }
            disposable = postAnswer.execute(token?.token!!, SavedAnswer(form.form_id, answers)).subscribe({
                //Post live data about success
            }, {
                //Post live data failure
            })
        }
    }, {
        //Post live data failure
    })
}

Но у меня сложилось впечатление, что это можно сделать лучше, но я не знаю как. По сути, я пытаюсь получить объект Token из базы данных, который возвращает Flowable Token? а затем используйте его для вызова postAnswer в цикле for, потому что мне нужно опубликовать каждый ответ отдельно (именно так разработан API). После этого postAnswer возвращает только Completable, но мне нужно сообщить Activity (это из кода ViewModel), сколько ответов было отправлено

Я думал об использовании функций .flatMap или .concat, но я не уверен, будет ли это полезно в этом случае. Кроме того, мне нужно назначить getToken.execute () одноразовым?

Спасибо за ваши ответы

EDIT:

Вот мой список вопросов:

private var questions: List<Form> = emptyList()

Заполняется функциями viewModel

1 Ответ

0 голосов
/ 25 января 2019

Попробуй подумать с вложенностью :) Это здесь, вероятно, подойдет: для каждого сохраненного ответа, отправь запрос .

disposable = getToken.execute()
   .switchMap { token ->  // switchMap because your old token is probably invalidated
      val savedAnswers = questions
            .map { form->                
                val formId = form.form_id

                form.answers
                   ?.filter { it.isChecked }
                   ?.map { it.answer_id }
                   ?.let { SavedAnswer(formId, answersIds) }
                   ?: SavedAnswer(formId, emptyList() ) // if no checked answer, then return empty list of ids
            }

      Observable.list(savedAnswers)
            .concatMap { savedAnswer -> // concatMap because you want the whole list to be executed once per time, use flatMap if you want it to be in parallel.
                  postAnswer.execute(token?.token!!, savedAnswer) // FYI: !! is bad practice in Kotlin, try make it less anbiguous
            }
            .toList()
   }
   .subscribe({ listOfResultsFromPostings : List<SomeResultHere> ->
        //Post live data about success
    }, {
        //Post live data failure
    })
...