2016-06-11 2 views
1

Ich versuche, eine Funktion zu erstellen, die ein Objekt aus dem Realm liest und eine leere Observable ausgibt, wenn das Objekt nicht gefunden wird. Der Code funktioniert unten bis zu einem gewissen Grad, weil ich es mit dem Debugger stoppen und sehen, es ist genau die Observable.empty():Realm.firstFirstAsync(). AsObservable() arbeitet nicht konsistent mit RxJava.switchIfEmpty

fun readFromRealm(id: String): Observable<Player> { 
    return realm.where(Player::class.java) 
     .equalTo("id", id) 
     .findFirstAsync() 
     .asObservable<Player>() 
     .filter { it.isLoaded } 
     .flatMap { 
      if (it.isValid) 
       Observable.just(it) 
      else 
       Observable.empty() 
     } 
} 

Aber wenn ich versuche, der Code ein switchIfEmpty auf den beobachtbaren verwenden emittiert nie defaultPlayer, wenn sie nicht gefunden wird im Reich.

return readFromRealm(playerId) 
     .take(1) 
     .map{ // do something with emitted observable } 
     .switchIfEmpty(Observable.just(defaultPlayer)) // use this if no player found 

Das Merkwürdige ist, dass, wenn ich die ursprüngliche Methode aktualisieren, um umfassen ein first() vor dem flatMap:

fun readFromRealm(id: String): Observable<Player> { 
    return realm.where(Player::class.java) 
     .equalTo("id", id) 
     .findFirstAsync() 
     .asObservable<Player>() 
     .filter { it.isLoaded } 
     .first() // add first 
     .flatMap { 
      if (it.isValid) 
       Observable.just(it) 
      else 
       Observable.empty() 
     } 
} 

Alles beginnt wie erwartet, aber ich glaube, diese Version Auto Update töten, weil Es erfasst nur das erste Ergebnis, das nach dem Filter ausgegeben wird.

Ich versuche immer noch, Realm und Rx zu finden, also mache ich wahrscheinlich etwas Dummes.

EDIT: Ich habe ein Beispielprojekt erstellt, die das Problem verdeutlicht ich sehe - https://github.com/donaldlittlepie/realm-async-issue

+0

Ja. Die automatische Aktualisierung funktioniert weiterhin, aber Ihr Take (1) führt dazu, dass sich das Ereignis nicht weiter in der Kette fortpflanzt. –

+0

Probieren Sie 'findAllAsync()' aus und verwenden Sie 'map()', um 'if (count> 0) {return results.get (0); } else {null zurückgeben; } 'aber ich weiß nicht, wie man das in Rx schreibt, so ist dies ein Kommentar statt – EpicPandaForce

Antwort

0

Aus Gründen verstehe ich nicht ganz. Wenn Sie take(1) knapp über dem flatMap und unterhalb der filter bewegen sollte es korrekt funktionieren:

realm.where(Dog.class) 
      .equalTo("id", 0L) 
      .findFirstAsync() 
      .asObservable() 
      .cast(Dog.class) 
      .filter(new Func1<RealmObject, Boolean>() { 
       @Override 
       public Boolean call(RealmObject realmObject) { 
        return realmObject.isLoaded(); 
       } 
      }) 
      .take(1) // <== here 
      .flatMap(new Func1<Dog, Observable<Dog>>() { 
       @Override 
       public Observable<Dog> call(Dog realmObject) { 
        if (realmObject.isValid()) { 
         return Observable.just(realmObject); 
        } else { 
         return Observable.empty(); 
        } 
       } 
      }) 
      .map(new Func1<Dog, Dog>() { 
       @Override 
       public Dog call(Dog dog) { 
        dog.setName("mapped " + dog.getName()); 
        return dog; 
       } 
      }) 
      .switchIfEmpty(Observable.just(createDefaultDog())) 
      .subscribe(new Action1<Dog>() { 
       @Override 
       public void call(Dog dog) { 
        textView.setText(dog.getName()); 
       } 
      }, new Action1<Throwable>() { 
       @Override 
       public void call(Throwable throwable) { 
        textView.setText(throwable.toString()); 

       } 
      }); 

Meine beste Vermutung, dass vor ist, flatMap wiederholt genannt wurde, Rückkehr Observable.empty() mehrere Male. Vielleicht wirkt sich das auf eine unerwartete Weise auf die Beobachtbare Kette aus.

+0

Ich stimme zu, dass dieses Beispiel funktioniert. Ich habe auch versucht, Realm aus dem Bild zu nehmen, um sicherzustellen, dass alles in Ordnung ist. – donaldlittlpie

+0

Ich habe ein Beispielprojekt erstellt, das das Problem hervorhebt, das ich sehe https://github.com/donaldlittlepie/realm-async-issue. In 'MainActivity.java' habe ich zwei Textansichten, die basierend auf meinem Realm-Ergebnis aktualisiert werden sollten. Die Methode 'findEmptyInRealm' kommt nie zum Abo. – donaldlittlpie

+0

Danke für das Projekt. Ich habe meine Antwort mit meinen Ergebnissen aktualisiert –