user3806331 user3806331 - 2 months ago 28
Android Question

Realm Proper way of Copy Object In Transaction with RxJava

Currently, when copying a value to realm, i do the following:

public void addToRealm(Home item, RealmChangeListener<E> listener) {

realm.executeTransaction((Realm realm1) ->
realm1.copyToRealm(item).addChangeListener<Home>(listener));
}


And then i can access the newly added object inside the listener. What is the proper RxJava way of accomplishing the same? The observable must return
Observable<Home>
, which is the realmCopy not the original object. Can any1 please provide a sample?

Managed to get it working by doing this, altought im not sure it is the best approach... What is the recommended approach?

return Observable.just(homeItem)
.map { (HomeItem homeItem) ->
return AnotherHomeItem(homeItem.xxx, homeItem.yyy)
}
.flatMap { (AnotherHomeItem anotherItem) ->
realm.beginTransaction()
val newItem = realm.copyToRealm(anotherItem).asObservable< AnotherHomeItem >()
realm.commitTransaction()
return newItem
}
.filter {
return it.isLoaded
}

Answer

You should write to the Realm on a background thread, and observe with a different subscription on the UI thread.

I wrote this documentation example to show how that works.

You persist with one subscription on the background thread:

public Subscription downloadObjectsFromNetwork() {
    return objectApi.getObjects()
        .subscribeOn(Schedulers.io())
        .subscribe(response -> {
            try(Realm realmInstance = Realm.getDefaultInstance()) {
                realmInstance.executeTransaction(realm -> realm.insertOrUpdate(response.objects));
            }
        });
}

And you read with asObservable() on the UI thread:

public Subscription readFromRealm() {
    return realm.where(SomeObject.class)
         .findAllAsync()
         .asObservable()
         .subscribeOn(AndroidSchedulers.mainThread())
         .observeOn(AndroidSchedulers.mainThread())
         .filter(RealmResults::isLoaded)
         .subscribe(objects -> adapter.updateData(objects));
}