title: RXSwift + Moya + Error Handling + Refresh Button
body: <p>I am trying to set up a tableview that refreshes user data after a button is pressed. RXSwift is used for the entire chain of events. Moya is used for routing. </p>
  
  <p>I am trying to use the standard error handling given by Moya, which is:</p>
  
  
  
  <pre><code>provider.rx.request(.userProfile("ashfurrow")).subscribe { event in
      switch event {
      case let .success(response):
          image = UIImage(data: response.data)
      case let .error(error):
          print(error)
      }
  }
  </code></pre>
  
  <p>The only way I have been able to get this to work, is to use an inner subscribe method. Please see code below. Can anyone think of a way that does not require an inner subscribe? It seems a bit clumsy as is.</p>
  
  
  
  <pre><code>class ViewController: UIViewController {
      @IBOutlet weak var refreshBtn: UIButton!
      @IBOutlet weak var tableView: UITableView!
  
      let provider = MoyaProvider&lt;MyAPI&gt;()
  
      let disposeBag = DisposeBag()
  
      var latestUsers = Variable&lt;[User]&gt;([])
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          setupObservableBtnRefreshWithDataFetch()
          bindDataToTableView()
      }
  
      func setupObservableBtnRefreshWithDataFetch() {
          let refreshStream = refreshBtn.rx.tap.startWith(())
  
          let responseStream = refreshStream.flatMapLatest { _ -&gt; SharedSequence&lt;DriverSharingStrategy, [User]&gt; in
              let request = self.provider.rx.request(.showUsers)
  
              // Inner Subscribe here, to be able to use the standard Moya subscribe methods for error handling
              request.subscribe { event in
                  switch event {
                  case .success(let user):
                      print("Success")
                  case .error(let error):
                      print("Error occurred: \(error.localizedDescription)")
                  }
              }
  
              return request
                  .filterSuccessfulStatusCodes()
                  .map([User].self)
                  .asDriver(onErrorJustReturn: [])
          }
  
          let nilOnRefreshTapStream: Observable&lt;[User]&gt; = refreshBtn.rx.tap.map { _ in return [] }
          let tableDisplayStream = Observable.of(responseStream, nilOnRefreshTapStream)
              .merge()
              .startWith([])
  
          tableDisplayStream
              .subscribe { event in
                  switch event {
                  case .next(let users):
                      print("Users are:")
                      print(users)
                      self.latestUsers.value = users
                      break
                  case .completed:
                      break
                  case .error(let error):
                      print("Error occurred: \(error.localizedDescription)")
                      break
                  }
              }
              .disposed(by: self.disposeBag)
      }
  
      func bindDataToTableView() {
          latestUsers.asObservable()
              .bind(to: tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) { (_, model: User, cell: UITableViewCell) in
                  cell.textLabel?.text = model.login
              }
              .disposed(by: disposeBag)
      }
  }      
  
  class User: Decodable {
      var name: String?
      var mobile: Int?
      var userRequestedTime: String?
      var login: String?
  
      init(name: String, mobile: Int, login: String = "") {
          self.name = name
          self.mobile = mobile
          self.login = login
      }
  }
  </code></pre>