I call two independent API calls using Obeservable.zip(). In this case, if the first API fails(returning some kind of error), the second API never executes inside the subscribe(onNext) closure even if it is successful. and vice versa. I still want the success case and failure case from each api call.
How can I solve this issue using Observable zip or should I use another method to achieve this?
Observable.zip(api1(), api2())
.subscribe { [weak self] in
print($1) //if the first api call fails, Nothing prints out here.
}
.onError: {
print("error", $0)
}
.disponseBag(by: disposebag)
It's not just if the first fails. If either Observable fails, the other will be disposed and your onNext will not be called.
There are a few different ways to solve this, and they all involve turning the error
event into a next
event.
You could use:
Observable.zip(api1.materialize(), api2.materialize())
.subscribe(
onNext: { lhs, rhs in
switch (lhs, rhs) {
case let (.next(left), .next(right)):
print(left, right)
case let (.error(left), .next(right)):
print(left, right)
case let (.next(left), .error(right)):
print(left, right)
case let (.error(left), .error(right)):
print(left, right)
default:
return
}
},
onError: { _ in /*will not get called*/ })
or you if you don't care about the errors, you could convert them to Optionals:
Observable.zip(
api1.map(Optional.some).catch { _ in .just(nil) },
api2.map(Optional.some).catch { _ in .just(nil) }
)
.subscribe(
onNext: { lhs, rhs in
print(lhs as Any, rhs as Any) // errors will be `nil`
},
onError: { _ in /*will not get called*/ })
If you don't need the results of both network calls to do work, then another option would be to just keep the two requests separate:
api1
.subscribe(onNext: { print($0) }, onError: { print($0) })
api2
.subscribe(onNext: { print($0) }, onError: { print($0) })