PAK
PAK

Reputation: 441

RxSwift: Completable concat in a deferred way

Can anybody tell me if it is possible to create a deferred completable in a concat operator.

I want to fetch a session, and after this load a user with the corresponding session id.

SessionAPI.post(email: email, password: password)
UserAPI.get(id: Session.load()!.userId)

Until now I used observables with the flatMap operator.

I will now try to reproduce the same behaviour with the completables, which doesn't have flatMap operator.

Working code with observables:

SessionAPI.post(email: email, password: password)
          .flatMap { (_) -> Single<Any> in
              return UserAPI.get(id: Session.load()!.userId)
          }

New working code with completables

SessionAPI.post(email: email, password: password)
          .concat(Completable.deferred { UserAPI.get(id: Session.load()!.userId) } )

I now want to create an extension for this deferred completable, like:

SessionAPI.post(email: email, password: password)
          .concatDeferred(UserAPI.get(id: Session.load()!.userId))

Current extension:

extension PrimitiveSequenceType where Self.Element == Never, Self.Trait == RxSwift.CompletableTrait {

    func concatDeferred(_ second: RxSwift.Completable) -> RxSwift.Completable {
        return Completable.deferred { () -> PrimitiveSequence<CompletableTrait, Never> in
            return second
        }
    }
}

Issue: The Session.load()! in UserAPI.get is loaded and crashing before SessionAPI.post finished.

Does someone got an idea to get this extension up running?

Thanks!

Upvotes: 1

Views: 1244

Answers (1)

Daniel T.
Daniel T.

Reputation: 33967

I'm going to assume that the reason you want to defer your UserAPI.get(id:) is because some "magic" is happening in the background where SessionAPI.post(email:password:) is making it so Session.load() is valid.

What this tells me is that the post(email:password:) should not be completable in the first place. Rather it should return an Observable<T> where T is whatever Session.load() returns.

You can't make the code work like you want:

SessionAPI.post(email: email, password: password)
    .concatDeferred(UserAPI.get(id: Session.load()!.userId))

With the above code, Session.load() will get called before SessionAPI.post(email:password:) is even called no matter what code you put in concatDeferred.

The Session.load() function must be called before concatDeferred is so that the former can pass its result into the latter.

Upvotes: 0

Related Questions