Search code examples
androidrx-javarx-java2

Return value from DB operation in Single<Long>


I am adding a record in my database (Room) and it returns the ID of the inserted record. For example, I add a row and it returns the number 5 (which is a Long).

When that operation is complete, I need to pass that ID to another function. When this 2nd function is complete, I need to return the ID which I got from step 1.

I am using RxJava and I am subscribing to the response, as I need to perform another action when this is complete, using the DB record ID.

See below:

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveUserData(date: UserDataDatabaseModel): Long

This returns the Long of the row ID.

I call it like this:

override fun submitUserData(): Single<Long> {
    var rowId: Long = -1
    return Completable.fromAction {
        rowId = dao.saveUserData(getUserData())
    }.andThen { 
        uploadUserData(rowId)
    }.andThen(Single.just(rowId))
}

At the call point, I do this:

submitUserData()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .doOnError { throwable -> throwable.printStackTrace() }
        .subscribe({ rowId ->
            //handle rowId
        },{
            //handle error
        })

The issue I have is that the code never returns to the subscribe. If I debug and use LogCat etc, then the last place I see the code being called is in the .andThen(uploadUserData()) code.

So I think I need to replace the Completable part of the code and replace it with something like Single.create(). I did try this already and got a similar problem where the code stopped executing after the first block, like it wasn't being subscribed to.

Can anyone help me with this? Thanks


Solution

  • First of all you don't need additional variable outside the reactive flow, and now

    1. why don't you just call

      Single.fromCallable{ dao.saveUserData(getUserData()).apply { uploadUserData(it) //non rx call } }

    2. if you really need to split calls to different Observables

      Single.fromCallable{ dao.saveUserData(getUserData()) } .flatMap { rowId -> uploadUserData(rowId).map {_ -> rowId }}