Search code examples
androidkotlinrx-javarx-java2

RxJava combine Single with Completable


I am confused how to use Single with Completable properly.
I have a get method that returns Single and a other method just do saving data and return nothing ( Completable )
Code looks like below :

fun getUserInfo() : Single<UserInfo>

fun save(token: Token) : Completable

fun initialize() {
    getUserInfo()
        .flatMap { 
            // Get token from UserInfo : val token = userInfor.getToken()
            // Call save(token: Token) method to save data
        }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeBy(
            onSuccess = {
                // HERE:  Using UserInfo to do somtehing
            },
            onError = {
                Log.d(it)
            }
        )
}  

How to write code inside flatMap block ? ( Or is there other operator suitable with this use case?)
Thank you


Solution

  • You can use flatMapCompletable:

    fun initialize() {
        getUserInfo()
            .flatMapCompletable { userInfo: UserInfo ->
                // save userInfo somewhere. i.e:
                this@MyActivity.userInfo = userInfo
                val token = userInfo.getToken()
                return@flatMapCompletable save(token) 
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeBy(
                onComplete = { // <--------- this becomes onComplete instead of onSuccess
                    // Here, you can use userInfo that you saved
                },
                onError = {
                    Log.d(it)
                }
            )
    }  
    

    Note that in your subscribeBy(...) method, don't forget to change the callback function name from onSuccess(...) to onComplete(...) since you're transforming single to completable.

    Alternatively, if you want to keep userInfo as a local variable, you can use toSingleDefault(...) to emit it downstream once the completable from your save(...) method has finished executing:

    fun initialize() {
        getUserInfo()
            .flatMap { userInfo: UserInfo -> // change back to flatmap
                val token = userInfo.getToken()
                return@flatMap save(token).toSingleDefault(userInfo) 
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeBy(
                onSuccess = { userInfo: UserInfo ->
                    // do something with userInfo ...
                },
                onError = {
                    Log.d(it)
                }
            )
    }