Observation chain in sequence, as you want to do in your code
As for your sample code, if you want to bind Observables (starting another after the previous emissions), use flatMap (or switchMap ) for this purpose:
this.serviceA.get() .flatMap((res1: any) => this.serviceB.get()) .flatMap((res2: any) => this.serviceC.get()) .subscribe( (res3: any) => { .... });
This practice is better than nesting, as it will make everything clearer and help you avoid callback addons, which Observable and Promises should have helped prevent in the first place.
Also, consider using switchMap instead of flatMap , basically it will allow you to “cancel” other requests if the first of them returns a new value. It's nice to use it if the first Observable that fires the rest is some kind of click event on a button, for example.
If you don’t need your various requests to wait for each other in turn, you can use forkJoin or zip to start them all at once, see @Dan Macak answer for more information and other ideas.
Angular 'async' and Observables work well together
As for Observables and Angular, you can ideally use | async | async pipe in Angular template instead of subscribing to Observable in its component code to get the values ​​emitted by this Observable
ES6 async / await and Promises instead of Observables?
if you don’t feel that you are using Observable directly, you can simply use .toPromise() in your Observable and then some async / wait statements.
If your Observable should return only one result (as is the case with the main API calls), Observable can be considered as completely equivalent to the promise.
However, I'm not sure if this should be done, given all the materials that Observable already provides (to readers: educational counter-examples are welcome!). I would like to use Observables more whenever possible as a training exercise.
Some interesting blog article about this (and there are many others):
https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875
The toPromise function is actually a bit complicated, because it is really an “operator”, but rather its RxJS-specific means of subscribing to the Observation and assuring it of a promise. The promise will be resolved to the last emitted value of the Observed after the Observed is completed . This means that if the Observer emits a hello value then waits 10 seconds before it ends, a promise is returned that will wait 10 seconds before allowing a hello. If the observable never ends, then the promise is never resolved.
NOTE: using toPromise () is antipattern unless youre dealing with an API that Promise expects, such as async-wait
(my emphasis)
The example you requested
By the way, it will be nice if someone can give me sample code to solve this with async / await: D
Example, if you really want to do this (maybe with some errors, you can’t check right now, please feel free to fix it)
// Warning, probable anti-pattern below async myFunction() { const res1 = await this.serviceA.get().toPromise(); const res2 = await this.serviceB.get().toPromise(); const res3 = await this.serviceC.get().toPromise(); // other stuff with results }
In case you can run all the requests at the same time, await Promise.all() , which should be more efficient, because none of the calls depends on the result of each other. (how forkJoin do with observables)
async myFunction() { const promise1 = this.serviceA.get().toPromise(); const promise2 = this.serviceB.get().toPromise(); const promise3 = this.serviceC.get().toPromise(); let res = await Promise.all([promise1, promise2, promise3]);