5

I am a beginner with rxjava/rxkotlin/rxandroid.

I need to deal with three diferent async-calls in a sequence. The problem is that the first step returns a Single<LocationResult>, the second a Completableand the third again a Completable.

(Single -> Completable -> Completable)

The problem is now that the last Completable depends on the data of the first Single

My current solution:

I think this is a bad solution, but I don't know how to do this right.

val ft = FenceTransaction(applicationContext, apiClient)
        stream
            .flatMap { locationResult ->
                ft.removeAll()
                return@flatMap ft.commit().toSingle({ return@toSingle locationResult })
            }
            .flatMapCompletable {
                ft.recycle()
                ft.setZone(it.location.longitude, it.location.latitude, ZONE_RADIUS)
                val dots = DotFilter().getFilteredDots()
                for (dot in dots) {
                    ft.addDot(dot)
                }
                return@flatMapCompletable ft.commit()
            }
            .subscribeBy(
                onComplete = {
                    "transaction complete".logi(this)
                },
                onError = {
                    "transaction error".logi(this)
                })

Is this approch the correct way to do it?

And how should I dispose the Completeables? Generally when should I dispose Observables?

Appyx
  • 1,145
  • 1
  • 12
  • 21

2 Answers2

1

No idea if you still have this issue but generally for Single->Completable->Completable you'd do:

val disposable = service.getSingleResult()
                        .flatMapCompletable { locationResult ->
                            callReturningCompletable(locationResult)
                        }
                        .andThen { finalCompletableCall() }
                        .subscribe({...}, {...})
Andrew G
  • 1,547
  • 1
  • 13
  • 27
  • 1
    thx, but i asked how to get the result from the first single after the last completable – Appyx Apr 25 '18 at 01:55
0
fun demo(): Completable {
    return Single
        .fromCallable {
            "lol" // original value from single
        }.flatMap { // "lol" become the param of this flatmap lambda
            Completable
                .fromCallable { Log.d("xxxx", "$it, completable 1") }
                .andThen(
                    Single.fromCallable { it } // `it` is "lol" we create a new single to continue pass the value downstream
                )
        }.flatMapCompletable { // "lol" again become the param of the lambda here
            if (it == "lol") { // we can now access the "lol" here
                Completable.fromCallable { Log.d("xxxx", " completable 2 HAPPY") }
            } else {
                Completable.fromCallable { Log.d("xxxx", " completable 2 SAD") }
            }
        }
}

Demo of Single -> Completable -> Completable, I think main thing is just to chain a Single after the first Completable, that returns the value of the original Single.

This will make the chain looks like: Single "value 1" -> Completable -> Single "value 1" -> Completabe, this will make the the last clause flatMapCompletable access the original value 1 and therefore we can decide which Completable to use at the very end.

Haomin
  • 1,265
  • 13
  • 12