chr0x
chr0x

Reputation: 1251

Wait multiple observable requests to finish using RXSwift

I have a list of observables that are requests for google distance and duration info from an specific point. I'm trying to load my screen only when all this information is fetched, but my subscribe on next for those observables are never called (the line "observer.onNext(viewModel)" is called and has the information already fetched, only the subscribe(onNext) is not being called). How can I wait til those observables complete?

func stationInfoObservable(userLocation: CLLocationCoordinate2D, stations: [Station]) -> [Observable<GasStationTableCellViewModel>] {

    var observables: [Observable<GasStationTableCellViewModel>] = []

    for station in stations {
        observables.append(Observable.create({ observer in
            guard let toCoordinate = station.coordinate() else { return Disposables.create() }

            self.mapDirections.routes(from: userLocation.asPlace(), to: toCoordinate.asPlace()) { routes, error in
                if let error = error {
                    logger.error(error)
                } else {
                    guard let leg = routes.first?.legs?.first else {
                        return
                    }

                    guard let distance = leg.distance?.text, let duration = leg.duration?.text else { return }
                    station.distanceInKMFromUserLocation = distance
                    station.distanceInMinutesFromUserLocation = duration

                    let viewModel = GasStationTableCellViewModel(station: station)

                    observer.onNext(viewModel)
                    observer.onCompleted()
                }
            }
            return Disposables.create()
        }))
    }

    return observables
}

I'm trying to subscribe this way (EDIT: I'm now trying to use zip, but the the drive / subscribe continues not being called):

Observable.zip(observables)
            .asDriver(onErrorJustReturn: [])
            .drive(onNext: { test in
                print(test)
            }, onCompleted: {
                print("aa")
            }).disposed(by: DisposeBag())

Upvotes: 2

Views: 2519

Answers (1)

dalton_c
dalton_c

Reputation: 7171

Based on your subscription code, it looks like you're not retaining the DisposeBag. You must retain this object because when it gets deallocated, all disposables it owns get immediately disposed. Try making it a property and use the property:

class MyClass {
    let disposeBag = DisposeBag()

    func setupSubscription() {
        Observable.zip(observables)
            .asDriver(onErrorJustReturn: [])
            .drive(onNext: { test in
                print(test)
            }, onCompleted: {
                print("aa")
            }).disposed(by: disposeBag)
    }
}

Upvotes: 4

Related Questions