7
votes

I trying to implement the pattern Repository using Realm and RxJava. The repository interface has a signature like this

Observable<List<T>> query(Specification specification);

So, when I am working with Realm and would like to retrieve the result "asObservable", I get Observable>. I couldn't find a way to transform Observable> into Observable>.

Can anybody give a hand to resolve this?

I tried sth like this

final Observable<RealmResults<PlantRealm>> realmResults = realm.where(PlantRealm.class)
               .equalTo(PlantTable.ID, "1")
               .findAll().asObservable();

// convert Observable<RealmResults<PlantRealm>> into Observable<List<PlantRealm>>

    return realmResults.flatMap(Observable::from).toList().map(list -> {

                for (PlantRealm plantRealm : list) {
                    plants.add(toPlant.map(plantRealm));
                }
                return Observable.from(plants);
            }
    );

But the type check system is still complaining....

return Observable.create( subscriber -> {

       final Realm realm = Realm.getInstance(realmConfiguration);
       final RealmResults<PlantRealm> realmResults = realm.where(PlantRealm.class)
               .equalTo(PlantTable.ID, "1")
               .findAll();

       final List<Plant> plants = new ArrayList<>();

       for (PlantRealm plantRealm : realmResults) {
           plants.add(toPlant.map(plantRealm));
       }

       realm.close();

       subscriber.onNext(plants);
       subscriber.onCompleted();
   });
3
Doesn't RealmResults<T> implement the List<T> interface? - JohnWowUs
@JohnWowUs Yes. But I imagine that there should be a better way to do this. I think so, you are refering to new ArrayList<Plant>(Arrays.asList(realmResults.toArray())). right? - Ignacio Giagante
No. I mean RealmResults<T> already implements List<T>. Look up the class at here. Note that List<T> is an Interface not a class. - JohnWowUs

3 Answers

2
votes

After watching Dan Lew's Conference about Common RxJava Mistakes (mistake flattening list), I found a common mistake related to this case.

So, the solution for this case is the following.

realmResults.flatMap(list ->
            Observable.from(list)
                    .map(plantRealm -> toPlant.map(plantRealm))
                    .toList())

This video is awesome, I highly recommend to watch it.

I'm having problem with this solution if I want to access to the realm object from other Thread. I could resolve other corner case like this, but I'm still stuck with this.

code

console

I resolved this...

resolved

0
votes

You can do the following:

public Observable<List<AllTypes>> getList() {
  Observable<RealmResults<AllTypes>> obs = realm.where(AllTypes.class).findAll().asObservable();
  return (Observable) obs;
}
0
votes
return Single.create( e -> {
            ArrayList<SomeModel> arrayList = new ArrayList<>();
            realm.where(SomeModel.class)
                    .findAllSortedAsync("createdOn", Sort.DESCENDING)
                    .asObservable()
                    .filter(RealmResults::isLoaded)
                    .subscribe(someModelsAsRealmResult -> {
                        arrayList.addAll(someModelsAsRealmResult);
                        e.onSuccess(arrayList);
                    });
        });