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.