I have a quick question:
Observable<Result<String, RequestError>>
, let’s call it requestToken
String
(token) to do another request that returns Observable<Result<NSDictionary, RequestError>>
, let’s call it requestData
Observable<Result<String, RequestError>>
to Observable<Result<NSDictionary, RequestError>>
How can I achieve that without multiple nested levels in my code?
This is what I have today:
requestToken()
.flatMap({ result -> Observable<Result<NSDictionary, RequestError>> in
switch result {
case .success(let token):
return requestData(token: token).map({ $0.map({ $0 + ["token": token] }) })
case .failure(let error):
return Observable.of(.failure(error))
}
})
It's a detailed example, hope this may help:
enum RequestError: Error {
case unknown
}
func requestToken() -> Observable<String> {
return Observable.create { observer in
let success = true
if success {
observer.onNext("MyTokenValue")
observer.onCompleted()
} else {
observer.onError(RequestError.unknown)
}
return Disposables.create()
}
}
func requestData(token: String) -> Observable<[String: Any]> {
return Observable<[String: Any]>.create { observer in
let success = false
if success {
observer.onNext(["uid": 007])
observer.onCompleted()
} else {
observer.onError(RequestError.unknown)
}
return Disposables.create()
}
.map { (data: [String: Any]) in
var newData = data
newData["token"] = token
return newData
}
}
requestToken() // () -> Observable<String>
.flatMapLatest(requestData) // Observable<String> -> Observable<[String: Any]>
.materialize() // Observable<[String: Any]> -> Observable<Event<[String: Any]>>
.subscribe(onNext: { event in
switch event {
case .next(let dictionary):
print("onNext:", dictionary)
case .error(let error as RequestError):
print("onRequestError:", error)
case .error(let error):
print("onOtherError:", error)
case .completed:
print("onCompleted")
}
})
.disposed(by: disposeBag)
I think it's much easier to achieve it using materialize()
with less extra work:
func requestToken() -> Observable<String> { return .empty() }
func requestData(token: String) -> Observable<NSDictionary> { return .empty() }
enum RequestError: Error {}
requestToken()
.flatMapLatest(requestData)
.materialize()
.subscribe(onNext: { event in
switch event {
case .next(let dictionary):
print("onNext:", dictionary)
case .error(let error as RequestError):
print("onRequestError:", error)
case .error(let error):
print("onOtherError:", error)
case .completed:
print("onCompleted")
}
})
.disposed(by: disposeBag)
Hope this may help.