0

I've wanted to try RxJava with kotlin to make coding easier, so I've produced this:

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

But I have an impression it can be done better, but I do not know how. Basically what I am trying to achieve is getting a Token object from database, that returns Flowable Token? and then use it to call postAnswer in a for cycle, because I need to post each answer separately (That's how the API is designed). After that, postAnswer only returns Completable, but I need to let the Activity know (this is from ViewModel code) how many answers were posted

I've thought about using .flatMap or .concat functions, but I am not sure if it will be helpful in this case. Also, do I need to assign getToken.execute() to disposable?

Thank you for your answers

EDIT:

Here is my questions list:

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

It gets filled by viewModel functions

Lukas Anda
  • 716
  • 1
  • 9
  • 30
  • You are doing it wrong, t should all done in a single Rx stream. What is `questions` object? Copy your class here or at least all objects used here to provide more information in order to help you. – DawidJ Jan 06 '19 at 12:33
  • @DawidJamroży oops sorry, the questions is just a simple list of objects, I've edited my question – Lukas Anda Jan 06 '19 at 12:52

1 Answers1

1

Try to think with nesting :) This here will probably do: for each saved answer, post a request.

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
    })
Diolor
  • 13,181
  • 30
  • 111
  • 179