I have a refreshTrigger and BehaviourRelay of items:
var refreshTrigger = PublishSubject<Void>()
var rootItems: BehaviorRelay<[Codable]> = BehaviorRelay(value: [])
Then, I use UITextField to run search query when user enters text:
let queryText = queryTextField.rx.text.orEmpty
.throttle(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
Finally, I have an observable which combines this observable with additional trigger to refresh manually:
let refreshText = refreshTrigger.withLatestFrom(queryText)
Observable.merge(refreshText, queryText)
.flatMapLatest { [weak self] query -> Observable<[Codable]> in
guard let strongSelf = self else { return .empty() }
let ctgs = try strongSelf.getCategories()
.startWith([])
.catchErrorJustReturn([])
let itms = try strongSelf.getSearchResults(query)
.retry(3)
.startWith([])
.catchErrorJustReturn([])
return Observable.merge(ctgs, itms)
}
.bind(to: rootItems)
.disposed(by: disposeBag)
As you can see, I want to send 2 requests: fetch categories and items, because I'm displaying them in the same UITableView. It sends both requests at the same time, but first result disappear when the second comes in. But I use merge, so it should work.
Why it doesn't show combined results?
Headers of the getCategories and getSearchResults looks like this:
func getSearchResults(_ text: String) throws -> Observable<[Codable]>
func getCategories() throws -> Observable<[Codable]>
they both use alamofire's rx extension to run queries.