DesperateLearner
DesperateLearner

Reputation: 1175

RxSwift - Use two observable to make a async call

Lets say I have a function that takes in two arguments - Observable<String?> and Observable<Person?> and returns Observable

This is my sample code below:

return  Observable.combineLatest(self.id, personStream)
                  map { [weak self] (id,person) -> Person? in

     guard let person = person as? Person else {
       return nil
     }

    if let id = id {
       // How do I return this updated person
       self?.updatePersonDetails(for: person, completion: { (updatedPerson) in
            return updatedPerson
       })     
    } else {
       return person
    }
}

How do I return this updated person inside this mapping function?

Update:

public func updatePerson(personStream: Observable<Person>) -> Observable<Person> {
    return Observable.combineLatest(
            self.id,
            personStream
        ).flatMap { [weak self] (id,person) -> Observable<Person?> in

            guard let person = person as? Double else {
                return Observable.just(nil)
            }

            if let id = id {
                // How do I return this updated person
                return Observable.create { [weak self] observer in
                    self?.updatePersonDetails(for: person, completion: { (updatedPerson) in
                        observer.on(.next(updatedPerson))
                        observer.on(.completed)
                    })
                    return Disposables.create()
                }
            } else {
                return Observable.just(person)
            }
        }
}

The above function is called as below:

let personUpdateStream = personService.updatePerson(personStream: personDataStream)
Observable.combineLatest(personUpdateStream, nameStream,profileEnabledStream)
.subscribe(onNext: { [weak self] (person, name, isEnabled) in
                print(name)
                self?.updatePersonView(person: person, name: name, isLocked: !isEnabled)
            })
            .disposed(by: disposeBag)

Issue: The block inside combineLatest with the print(name) never runs. May I know whats the issue here?

Description of personUpdateStream

personUpdateStream RxSwift.FlatMap<(String?, Person?), RxSwift.Observable<Person?>> 0x0000604001e5af70

Upvotes: 1

Views: 1550

Answers (1)

Timofey Solonin
Timofey Solonin

Reputation: 1403

You should use flatMap instead of map and to integrate your non Rx call of updatePersonDetails you should use Observable.create.

Your final code should look something similar to:

return Observable.combineLatest(
            self.id,
            personStream
        ).flatMap { [weak self] (id,person) -> Observable<Person?> in

            guard let person = person as? Double else {
                return Observable.just(nil)
            }

            if let id = id {
                // How do I return this updated person
                return Observable.create { [weak self] observer in
                    self?.updatePersonDetails(for: person, completion: { (updatedPerson) in
                        observer.on(.next(updatedPerson))
                        observer.on(.completed)
                    })
                    return Disposables.create()
                }
            } else {
                return Observable.just(person)
            }
        }

Upvotes: 2

Related Questions