Reputation: 335
I'm still learning Rx and I'm trying to use RxSwift to make 3 requests that return depend on each other.
* DocumentsA
- CollectionA
* DocumentsB
- CollectionB
* DocumentsC
- CollectionC
The models are something like this:
struct DocumentA {
let documentsB: [DocumentB]
}
struct DocumentB {
let documentsC: [DocumentC]
}
struct DocumentsC {
let name: String
}
So using RxSwift, I'm trying to request each level of the document using separate methods for each document:
func fetchDocumentsA() -> Observable<DocumentA> {
return Observable.create { observer in
fetchDocumentsB().subscribe(onNext: { documentB in
if let documentA = DocumentA(documentB: documentB) {
observer.onNext(documentA)
}
}, onError: nil, onCompleted: {
observer.onCompleted()
}, onDisposed: nil).disposed(by: self.disposeBag)
return Disposables.create()
}
}
func fetchDocumentsB() -> Observable<DocumentB> {
return Observable.create { observer in
fetchDocumentsC().subscribe(onNext: { documentC in
if let documentB = DocumentB(documentC: documentC) {
observer.onNext(documentB)
}
}, onError: nil, onCompleted: {
observer.onCompleted()
}, onDisposed: nil).disposed(by: self.disposeBag)
return Disposables.create()
}
}
func fetchDocumentsC() -> Observable<DocumentC> {
return Observable.create { observer in
fetchName().subscribe(onNext: { name in
observer.onNext(DocumentC(name: name))
}, onError: nil, onCompleted: {
observer.onCompleted()
}, onDisposed: nil).disposed(by: self.disposeBag)
return Disposables.create()
}
}
Is there a better way to do this? It seems very convoluted.
Upvotes: 0
Views: 1682
Reputation: 584
In this case you can make this much nicer with map function, like in example bellow.
The Map operator applies a function of your choosing to each item emitted by the source Observable, and returns an Observable that emits the results of these function applications. ReactiveX
func fetchDocumentsA() -> Observable<DocumentA> {
return fetchDocumentsB().map { (documentB) -> DocumentA in
DocumentA(documentB: documentB)
}
}
func fetchDocumentsB() -> Observable<DocumentB> {
return fetchDocumentsC().map { (documentC) -> DocumentB in
DocumentB(documentC: documentC)
}
}
func fetchDocumentsC() -> Observable<DocumentC> {
return fetchName().map { (name) -> DocumentC in
return DocumentC(name: name)
}
}
Upvotes: 2