Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava Single to Completable to Single - how to pass the result of the first Single to the second Single

In the following method, how do I pass the result of the first Single to the second Single?

As it's written now, when it returns, somethingId is empty. If I change the value in the returned Single.just(somethingId) to something other than the empty string it will return that value.

What's interesting is that if I breakpoint into the method it stops on line 7 before it goes to line 5 and 6.

The documentation for the andThen on line 7 says:

Returns a Single which will subscribe to this Completable and once that is completed then will subscribe to the {@code next} SingleSource.

Why does it seem to be executing in that order and/or is there a better way to do this?

1 override fun downloadSomething(): Single<String> {
2    var somethingId = ""
3    return remoteDataSource.downloadSomething() // this is a Single
4        .flatMapCompletable { something ->
5            somethingId = something.id
6            saveSomething(something) // this is a Completable
7        }.andThen(Single.just(somethingId))
8 }

The only thing I can think to do at this point is return a Single for the saveSomething() method on line 6 (which works). However I'm then changing the signature of that method just so I can use it in this particular method which doesn't feel right. Surely there's a way to get this to work without doing that?

like image 482
Michael Vescovo Avatar asked Jan 02 '23 06:01

Michael Vescovo


1 Answers

You can achieve the same result without changing saveSomething method signature, if you avoid the flatMapCompletable operation altogether:

1 override fun downloadSomething(): Single<String> {
2    return remoteDataSource.downloadSomething() // this is a Single
3        .flatMap { something ->        
4            saveSomething(something).andThen(Single.just(something.id))
5        }
6 }

Or:

1 override fun downloadSomething(): Single<String> {
2    return remoteDataSource.downloadSomething() // this is a Single
3        .flatMap { something ->        
4           saveSomething(something).toSingleDefault(something.id)
5        }
6 }

The problem you are having at the moment is that Single.just(somethingId) is executed as part of the RxJava pipeline creation and as such, it happens before downloadSomething has finished, and therefore the value of somethingId is still an empty string.

like image 136
Jose Ignacio Acin Pozo Avatar answered Feb 25 '23 11:02

Jose Ignacio Acin Pozo