I am using angular 2 common http that return an Observable, but I face with a problem that my code likes a mesh when I use nested Observable call:
this.serv
As @Pac0 already elaborated on the various solutions well, I will just add slightly different angle.
I personally prefer not mixing Promises and Observables - which is what you get while using async await with Observables, because even though they look similar, they are very different.
Now even though it is sometimes valid to use both, especially with Angular I think one should consider going as far with RxJS as possible. The reasons being:
async
pipe which allows for composing your whole application data flow of streams which you filter, combine and do whatever modification you want on it without interrupting the stream of data coming from server without a single need for thening or subscribing. This way, you don't need to unwrap the data or assign it to some auxiliary variables, the data just flows from services through Observables straight to the template, which is just beautiful.There are some cases though where Promise still can shine. For example what I am missing in rxjs TypeScript types is concept of single. If you are creating an API to be used by others, returning Observable is not all that telling: Will you receive 1 value, many, or will it just complete? You have to write comment to explain it. On the other hand, Promise has much clearer contract in this case. It will always resolve with 1 value or reject with error (unless it hangs forever of course).
Generally, you definitely don't need to have only Promises or only Observables in your project. If you just want to express with a value that something was completed (deleting user, updating user), and you want to react on it without integrating it to some stream, Promise is the more natural way of doing so. Also, using async/await
gives you the power to write code in sequential manner and therefore simplifying it greatly, so unless you need advanced management of incoming values, you can stay with Promise.
So my recomendation is to embrace both the power of RxJS and Angular. Coming back to your example, you can write the code as following (credits for the idea to @Vayrex):
this.result$ = Observable.forkJoin(
this.serviceA.get(),
this.serviceB.get(),
this.serviceC.get()
);
this.result$.subscribe(([resA, resB, resC]) => ...)
This piece of code will fire 3 requests and once all of those request Observables have completed, subscription callback to forkJoin
will get you the results in an array, and as said, you can subscribe to it manually (as in the example) or do this declaratively using result$
and async
pipe in the template.
Using Observable.zip
would get you the same result here, the difference between forkJoin
and zip
is that the former emits only last values of inner Observables, the latter combines first values of the inner Observables, then second values etc.
Edit: Since you need the results of previous HTTP requests, use flatMap
approach in @Pac0's answer.