RxSwiftCommunity / RxRealm

RxSwift extension for RealmSwift's types
MIT License
1.15k stars 265 forks source link

Call add()/delete() not in subscribe, to return Observable/Completable #99

Closed alpex92 closed 4 years ago

alpex92 commented 6 years ago

Is it possible to call add() before subscribe, in flatmap or somehow else? I need to return a completable to subscribe later and listen to add completion/process error in another application layer.

func addPoint(point: POI) -> Completable { let points = [ point] let subscription = Observable .from(points) .subscribe(realm.rx.add()) // Needs Completable/Observable, not Disposable }

icanzilb commented 6 years ago

@alpex92 Realm.rx.add() is an Observer, not an Observable operator because it performs a side-effect. Further your subscription can emit multiple elements to which you subscribe so a Completable isn't a generic solution in there.

If you are looking to simply one-off add some element to a realm, what you need is:

func addPoint(point: POI) -> Completable {
  try? realm.write {
    realm.add(point)
  }
  // return whatever you need 
}

I don't think you need to create observable at all in your example.

alpex92 commented 6 years ago

I understand your point. I just expected other behavior: that add() will return observable, to listen to write success/error. And I can use ignoreElements() to return Completable as I don't care about further data changes here. But it just writes data with no callback option.

icanzilb commented 6 years ago

Ok, good point. Before we had Single (not Completable) it didn't feel as such a clean solution for add() to be returning an observable sequence. But I can see a point in wanting to be able to safely perform side-effects only after the write transaction has completed. At present you can do something along the lines of this:

override func viewDidLoad() {
    super.viewDidLoad()

    _ = Observable.just(Lap())
        .flatMap {
            return self.writeObject($0)
        }
        .subscribe(onCompleted: {
            print("completed")
        })
}

func writeObject<O: Object>(_ o: O) -> Single<O> {
    do {
        let realm = try Realm()
        try realm.write {
            realm.add(o)
        }
        return Observable.just(o).asSingle()
    } catch let e {
        return Observable.error(e).asSingle()
    }
}

I'll ask for more opinions on the RxSwift Slack, thanks for pointing this out

M0rtyMerr commented 4 years ago

Closing this, because the problem seems to be resolved