简体   繁体   中英

Listening to Room database insert with RXJava

I have a simple Android application with Room database and I am trying to react to an @Insert query with RxJava but I am unable to chain the calls correctly.

This is my view model method calling the insert:

fun insertTopic(): Single<Long> {
        val topic = Topic(null, topicText.value!!, difficulty.value!!, false)

        return Single.create<Long> { Observable.just(topicDao.insert(topic)) }
    }

And this is the code in my activity triggering the save action:

disposable.add(RxView.clicks(button_save)
            .flatMapSingle {
                viewModel.insertTopic()
                    .subscribeOn(Schedulers.io())
            }.observeOn(AndroidSchedulers.mainThread())
            .doOnError { Toast.makeText(this, "Error inserting topic", Toast.LENGTH_SHORT).show() }
            .subscribe { id ->
                // NOT INVOKED
                hideKeyboard()
                Toast.makeText(this, "Topic inserted. ID: $id", Toast.LENGTH_SHORT).show()
                this.finish
            })

When I click the button, the entity is saved but none of the subscribe code is invoked (no toast is shown). Could someone point out to me what am I doing wrong? I am fairly new to RX java.

The problem is in incorrect usage of Single.create . There is no need in wrapping topicDao.insert(topic) into Observable . Moreover, you are implementing new Single manually, which means you must pass the result id to the @NonNull SingleEmitter<T> emitter argument. But there is no need in using Single.create here.

Single.fromCallable is exactly what you need:

fun insertTopic(): Single<Long> = Single.fromCallable {
    val topic = Topic(null, topicText.value!!, difficulty.value!!, false)
    return@fromCallable topicDao.insert(topic)
}

Please note, that I create topic object inside lambda so that it isn't captured in a closure. Also keep in mind that fromCallable may throw UndeliverableException if you unsubscribe from Single during the lambda code execution. It will probably never happen in your specific case, but you should understand RxJava2 error handling design.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM