Search code examples
iosswiftrx-swiftrx-cocoa

How to combine two results from the different subjects and use latest one's result


I am having two view models. One for single contact management, other for whole contact list management.

And I have errors for both of them that can happen. In both cases I should apply same action - to show the error. But how I would do this more elegantly, so that every time, no matter from which view model error came, to show it only based on which error came the last?

I have this code right now:

 private func observeErrors(){
        
        let popup = PopupViewController.instantiate()
        let popupActionHandler =  {
            popup.dismiss(animated: true, completion: nil)
        }
        
        contactsViewModel.error.subscribe(onNext: { error in
            print(error.localizedDescription)
            switch error {
        
            case .unknown:
                self.showPopup(popup: popup, popupTitle: "An unknown error occured".localized, popupMessage: "Please try again.".localized, buttonTitle: nil, actionHandler: popupActionHandler)
            case .serverResponse(let message):
                
                self.showPopup(popup: popup, popupTitle: "An error occured".localized, popupMessage: message, buttonTitle: nil, actionHandler: popupActionHandler)
                
            }
        }).disposed(by: disposeBag)
        
        contactViewModel.error.subscribe(onNext: { error in
            print(error.localizedDescription)
            switch error {
           
            case .unknown:
                self.showPopup(popup: popup, popupTitle: "An unknown error occured".localized, popupMessage: "Please try again.".localized, buttonTitle: nil, actionHandler: popupActionHandler)
            case .serverResponse(let message):
                
                self.showPopup(popup: popup, popupTitle: "An error occured".localized, popupMessage: message, buttonTitle: nil, actionHandler: popupActionHandler)
                
            }
        }).disposed(by: disposeBag)
    }

but this is duplicating. I tried with combineLatest, but I am not sure how determine what was the last error that occurred and to show only that?


Solution

  • I guess you can use

    Observable.merge
    

    So it takes n observables (which must have same element type) and attach single subscriber to both. They are merged into a single flow:

    Observable.merge(contactsViewModel.error, contactViewModel.error)
        .subscribe(onNext: { error in 
            // your logic for both observables
        })
        .disposed(by: disposeBag)