Bruno
Bruno

Reputation: 1032

Chain sequence observables with arguments

I'm fairly new to RxSwift, so I have the following problem, lets suppose I have 3 Observable example functions which return different observable types:

func observableFunc1(item1: DummyObject) -> Observable<AVURLAsset> {
    return Observable.create { observer in

        let something_with_AVURLAsset = AVURLAsset(url: URL(fileURLWithPath: "file"))

        observer.onNext(something_with_AVURLAsset)

        observer.onCompleted()

        return Disposables.create()
    }
}

func observableFunc2(item: AVURLAsset) -> Observable<Data> {
    return Observable.create { observer in

        let something_with_data = Data()

        observer.onNext(something_with_data)

        observer.onCompleted()

        return Disposables.create()
    }
}

func observableFunc3(_ params: [String:Any]) -> Observable<Any> {
    let disposeBag = DisposeBag()
    return Observable.create { observer in
        RxAlamofire.request(api.sendData(params)).debug().subscribe(
            onNext: { reponse in
                observer.onCompleted()
        },
            onError: { error in
                observer.onError(customError.theError("error"))
        }
            )
            .addDisposableTo(disposeBag)
        return Disposables.create()
    }
}

How can I execute these 3 functions sequentially with the return value of func1 to be used on func2 and then when func2 is completed finally run func3.

I hope I made the question clear enough, but then again I'm really new to RxSwift and I don't know if these operations are possible or not.

Upvotes: 0

Views: 652

Answers (1)

Daniel T.
Daniel T.

Reputation: 33967

Here's an example...

Assuming you have the three functions:

func func1() -> Observable<Data1>
func func2(_ data: Data1) -> Observable<Data2>
func func3(_ data: Data2) -> Observable<Data3>

Then you can:

let a = func1()
let b = a.flatMap { func2($0) }
let c = b.flatMap { func3($0) }

or:

let c = func1()
    .flatMap { func2($0) }
    .flatMap { func3($0) }

That said, your observableFunc3 is quite broken. You need to remove the dispose bag from it. As it stands, the network call will cancel before it starts.

If you really don't want it to emit any values then:

func observableFunc3(_ params: [String:Any]) -> Observable<Void> {
    return RxAlamofire.request(api.sendData(params))
        .filter { false }
}

The above will emit either a completed or an error but no next values.

Better would be to write it like:

func observableFunc3(_ params: [String:Any]) -> Observable<Void> {
    RxAlamofire.request(api.sendData(params))
        .map { _ in }
}

The above will emit one next and then a completed or an error. This is better because you can map or flatMap after it to have things happen once it's done.

Upvotes: 1

Related Questions