Reputation: 71
I need to create dependent API calls where the second one needs a value returned by the first one. First thing that comes to mind is using flatMap
ApiManager.shared
.createReport(report: report)
.flatMap { (report) -> Observable<Report> in
return ApiManager.shared.createReportStep(reportID: report.ID)
}
createReport
returns Observable<Report>
where after successfull call returns updated Report
model(with ID), after that I need to call API to create report step, where report.ID
is needed.
Everything looks and works fine with that code, but the problem comes when I need to do something after each of these steps(createReport
and createReportStep
). I placed code in onNext
block, but it is called only once, after both of the steps are completed.
Is there a way to receive onNext signal after both steps? I could use something like this:
ApiManager.shared
.createReport(report: report)
.concat(ApiManager.shared.createReportStep(reportID: report.ID))
Which would emmit two signals like I want, but then again where do I get updated report.ID
from to pass to createReportStep
?
Upvotes: 1
Views: 546
Reputation: 13651
If you don't mind the time component and only need to have access to both report
and what is returned by createReportStep(reportID:)
, you could go with creating a tuple in flatMap
's block
ApiManager.shared
.createReport(report: report)
.flatMap { (report) -> Observable<Report> in
return ApiManager.shared.createReportStep(reportID: report.ID)
.map { (report, $0) }
}
The resulting observable would contain both results in a tuple.
If the time component is important, you could do the following
let report = ApiManager.shared
.createReport(report: report)
.share()
let reportStep = report.map { $0.ID }.flatMap(ApiManager.shared.createReportStep)
Observable.concat([report, reportStep])
Here, the important bit is the share
call. It will ensure createReport
performs its work only once, but you would have two next events as requested.
Upvotes: 2