Search code examples
iosswiftobservablerx-swift

Swift Map Observable<T> to Observable<T>


Im confused about converting RxSwift Observable<T> to Observable<T>

I have function for networking like this:

func createOrder(request: AcquirebatchOrder) -> Observable<AcquirebatchOrderResult> {
    //Do networking stuff and will return with Observable<AcquirebatchOrderResult>
}

And I can call that function like this:

transferService.createOrder(request: request)

And I need to convert Observable<AcquirebatchOrderResult> to Observable<TransferSubmitResult> because I don't want to duplicate observeResultForShowUI with different parameter. I have tried this but failed:

let observableResult = transferService.createOrder(request: request).map {
acquirebatchOrderResult -> Observable<TransferSubmitResult> in
            let transferSubmitResult = TransferSubmitResult()
            //Doing something to convert data from acquirebatchOrderResult to transferSubmitResult
            Observable.just(transferSubmitResult)
}

observeResultForShowUI(result: observableResult)

private func observeResultForShowUI(result: Observable<TransferSubmitResult>) {
   result.subscribe { [weak self] (result: TransferSubmitResult) in
        //Do something with data
   } onError: { (error: Error) in
        //Handle error
   }
}

The error shown when passing observableResult to function observeResultForShowUI

Cannot convert value of type 'Observable<Observable<TransferSubmitResult>>' to expected argument type 'Observable<TransferSubmitResult>'

Thank you


Solution

  • You're needlessly nesting things.

    To go from Observable<A> to an Observable<B> using map, you need to give it a function of type (A) -> B.

    What you did was give it a function from (AcquirebatchOrderResult) -> Observable<TransferSubmitResult> (so your "B" is Observable<TransferSubmitResult>). Thus your result ended up as Observable<<Observable<TransferSubmitResult>>

    All you need is:

    let observableResult = transferService
        .createOrder(request: request)
        .map { _ in TransferSubmitResult() }
    

    Although it's odd that your TransferSubmitResult doesn't use the acquirebatchOrderResult at all.