skip to Main Content

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

Answers


  1. Chosen as BEST ANSWER

    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
                        }
                    })
            }
    

  2. 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)) })
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search