3

I am making 2 RX calls that are nested within each other and are co-dependent. There is an issue with the server (which cannot be solved right now for various reasons) which returns errors in the 2nd nested call.

Until this gets solved, I need to have it that if the 2nd call returns an error, the results of the first call are discarded as well. Right now, the entire iterative process stops the moment any of these error responses occur, and so my goal is to skip over them.

Here is what my call structure currently looks like:

 fun getAllDynamicUtterances(module: String) {

    var uttList: ArrayList<DynamicUtterance>? = ArrayList()
    rxSubs?.add(
        repository.getDynamicUtterances(module).map{res ->
            res.uttSets.forEach {utt ->
                    utt.module = res.module!!
                    utt.transferInputValues()
                    utt.generateDefaultFlatTree()
                    uttList?.add(utt)
                    insertDynamicUtterance(utt)
                    repository.updateDynamicUtteranceView(utt).blockingForEach {
                        utt.assignSelectionStrings(it)
                        repository.storeDynamicUttPieces(utt.inputUttPieces)
                        utt.uttLinearisations = it.linearisations
                        updateDynamicUtterance(utt)
                    }
            }
        }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe ({
                allDynamicUtterances?.postValue(uttList)
            },{
                Log.e("errorHandle",it.toString())
            })
    )
}

My thinking is to include an if statement that almost does a "peek" of the second call before proceeding, but I'm not sure how to go about it. This is what I came up with so far to give an idea of my thinking:

fun getAllDynamicUtterances(module: String) {

    var uttList: ArrayList<DynamicUtterance>? = ArrayList()
    rxSubs?.add(
        repository.getDynamicUtterances(module).map{res ->
            res.uttSets.forEach {utt ->
                    utt.module = res.module!!
                    utt.transferInputValues()
                    utt.generateDefaultFlatTree()
                if (doesNotReturnError(utt)){ // <- add this
                    uttList?.add(utt)
                    insertDynamicUtterance(utt)
                    repository.updateDynamicUtteranceView(utt).blockingForEach {
                        utt.assignSelectionStrings(it)
                        repository.storeDynamicUttPieces(utt.inputUttPieces)
                        utt.uttLinearisations = it.linearisations
                        updateDynamicUtterance(utt)
                    }
                }
            }
        }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe ({
                allDynamicUtterances?.postValue(uttList)
            },{
                Log.e("errorHandle",it.toString())
            })
    )
}

and then adding this function, or a function that performs what it is im trying to achieve in any case.

private fun doesNotReturnError(utt: DynamicUtterance): Boolean{
   rxSubs?.add(
       repository.updateDynamicUtteranceView(utt).subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread())
           .subscribe({
             //cant put a return here :(
           }, {
               Timber.e(it)
           })
   )
    //returning over here will return nothing wont it? 
}

I welcome comments on how to improve my getAllDynamicUtterances function

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Glenncito
  • 902
  • 1
  • 10
  • 23
  • Subscriptions are asynchronous, rather than returning a value from the `doesNotReturnError` method call why not pass the objects `uttList` and `utt` to it and then make use of them inside `subscribe({...` – Giddy Naya Sep 11 '19 at 13:02

1 Answers1

1

Sounds like a job for flatMap instead of map.

repository.getDynamicUtterances(module).flatMap{res ->
            res.uttSets.forEach {utt ->
                    utt.module = res.module!!
                    utt.transferInputValues()
                    utt.generateDefaultFlatTree()
            return if (doesNotReturnError(utt)){ // <- add this
                    uttList?.add(utt)
                    insertDynamicUtterance(utt)

                    repository.updateDynamicUtteranceView(utt).doOnNext {
                        utt.assignSelectionStrings(it)
                        repository.storeDynamicUttPieces(utt.inputUttPieces)
                        utt.uttLinearisations = it.linearisations
                        updateDynamicUtterance(utt)
                    }
                } else {
                   Observable.error(utt.getError())
                }
            }

Nathan Schwermann
  • 31,285
  • 16
  • 80
  • 91