How do I combine observe two result rx sequences and subscribe with one closure arguments?

200 views Asked by At

My sample is create call rest api two observable of result from load rx.request api from moya

func dataOneObservable() -> Observable<ObJectOneClass> {
        
        return myprovider.rx.request(API.loadDataDetail())
            .asObservable()
            .retry()
            .observeOn(MainScheduler.instance)
            .filterSuccessfulStatusAndRedirectCodes()
            .catchObjectError()
            .mapObject(ObJectOneClassResult.self)
            .map({ (response) -> ObJectOneClass in
                if ObJectOneClass.data != nil {
                    if let item = response.data {
                        return item
                    }
                    
                    return ObJectOneClass()
                }
                
                return ObJectOneClass()
            })
    } 

func dataTwoObservable() -> Observable<ObJectTwoClass> {
            
            return myprovider.rx.request(API.loadDataProfile())
                .asObservable()
                .retry()
                .observeOn(MainScheduler.instance)
                .filterSuccessfulStatusAndRedirectCodes()
                .catchObjectError()
                .mapObject(ObJectTwoClassResult.self)
                .map({ (response) -> ObJectTwoClass in
                    if ObJectTwoClass.data != nil {
                        if let item = response.data {
                            return item
                        }
                        
                        return ObJectTwoClass()
                    }
                    
                    return ObJectTwoClass()
                })
        } 

Then I want to combine result by use combineLastest of RxSwift but when I use .subscribe my response event can't passing result

my function call is same this:

    func testCombine(completion:@escaping(_ result:Result<(ObJectOneClass,ObJectTwoClass),Error>) -> ()){
        
    

        _ = Observable.combineLatest(dataOneObservable(), dataTwoObservable())
                .asObservable()
                .subscribe({ event in
    //Event<(ObJectOneClass,ObJectTwoClass)>
//case .next((a, b)):
                    switch event{
                        
                    case .next(response):
                        completion(.success(response))
                    case let .error(error):
                        completion(.failure(error as NSError))
                    default:
                        break
                    }
                })
        }

Then enter image description here

please help me guide to syntax completion this.

2

There are 2 answers

2
Daniel T. On BEST ANSWER

Here's an interesting solution:

func testCombine(completion: @escaping(_ result: Result<(ObJectOneClass, ObJectTwoClass), Error>) -> ()) {
    _ = Observable.combineLatest(dataOneObservable(), dataTwoObservable())
        .map(Result.success)
        .catch(combine(Result.failure, Observable.just))
        .subscribe(onNext: completion)
}

func combine<A, B, C>(_ f: @escaping (A) -> B, _ g: @escaping (B) -> C) -> (A) -> C {
    { g(f($0)) }
}

That map to Result.success, catch just Result.failure is really common when you are dealing with Result types. It's so common that you might want to make a single operator to capture the notion.

extension Observable {
    func toResult() -> Infallible<Result<Element, Error>> {
        map(Result.success)
            .asInfallible(onErrorRecover: combine(Result.failure, Infallible.just))
    }
}

In response to your comment, here's a somewhat less advanced version:

extension Observable {
    func toResult() -> Infallible<Result<Element, Error>> {
        map(Result.success)
            .asInfallible(onErrorRecover: { Infallible.just(Result.failure($0)) })
    }
}
0
Papon Smc On

OK This my topic can fix problem by declare let in .next

func testCombine(completion:@escaping(_ result:Result<(ObJectOneClass,ObJectTwoClass),Error>) -> ()){
        
    

        _ = Observable.combineLatest(dataOneObservable(), dataTwoObservable())
                .asObservable()
                .subscribe({ event in

                    switch event{
                        
                    case .next((let one,let two)):
                        completion(.success((one,two)))
                    case let .error(error):
                        completion(.failure(error as NSError))
                    default:
                        break
                    }
                })
        }