Abstract problem: Every time a source Observable emits and event, a sequence of API calls and Angular services need to be triggered. Some of those invocatio
You're right about these concerns and problems you mentioned but the problem I see here is turning your mindset from an imperative approach to a Reactive/Functional approach but let us review the imperative code first
private startUpload(event: StartUploadEvent) {
const headers = this.getAuthenticationHeaders(event)
const id = this.generateUploadId()
this.emitUploadStartEvent(id, event)
const pdfId = this.createPdfDocument(event, headers, id)
this.uploadBilderForPdf(event, pdfId, headers, id)
const cloudId = this.closePdf(headers, pdfId)
this.emitUploadDoneEvent(id, event, cloudId)
return cloudId
}
Here you see the stuff is more clean that you have event that you can pass and get only what you want and pass it to the next functions and we want to move this code to the Reactive/Functional approach.
the main problem from my point of view is that you made your function lose the context they have for example getAuthenticationHeaders should not return the event at all it should only return headers and the same for other functions.
when dealing with RxJS(aka Reactive Approach) you kind of deal with these issues a lot and that's ok as it keeps the functional concepts applied and keeps your code more predictable as pure operators should only deal with data at the same pipeline which keeps everything pure and not leading for side effects which will lead to unpredictable code.
I think what are you looking for will be solved with nested pipes (this is the best solution from my opinion)
concatMap(event => this.getAuthenticationHeaders(event).pipe(
map(headers => this.generateUploadId(event, headers).pipe())
))
and It is used heavily in some RxJS backend libraries like Marble.js
you can use approach which is similar to Result Selector:
concatMap(event => this.getAuthenticationHeaders(event).pipe(
map(headers => ({ headers, event }))
)),
or the great other solutions that people suggested will make it work but the you'll still have the same problems you mention but with more clean/readable code.
You can also turn it to async/await approach but you'll lose the reactivity that RxJS provide to you.
what I can suggest is to try to read more about the reactive programming and how you move your mindset to that and I'll provide some links here which I see is very great to start with and to try some libraries that built on top of RxJS like CycleJS and I recommend to read about Functional Programming which will help a lot also from this great books Mostly adequate guide to FP (in javascript) & Composing Software.
I recommend this great Talk RxJS Recipes which will change your way of using RxJS.
Useful Resources: