I am trying to improve my knowledge of Angular2 by migrating an application currently written in Angular1/AngularJS.
One feature in particular has me stumped. I am trying to replicate a feature where a calling function waits to proceed until the function it is calling has completed a loop of promises. In AngularJS, the function I am calling looks basically like this:
this.processStuff = function( inputarray, parentnodeid ) {
var promises = [];
var _self = this;
angular.forEach( inputarray , function( nodeid ) {
switch ( parentnodeid )
{
case ‘AAA’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
case ‘BBB’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
case ‘CCC’ : var component = _self.doMoreStuff( nodeid, parentnodeid ); break;
default : var component = null;
}
promises.push( component );
});
return $q.all(promises);
};
It contains a forEach
loop that calls another function (doMoreStuff
) that also returns a promise, and it stores all those returned promises in an array.
With AngularJS, when I call processStuff
in another function, I could count on the system waiting until processStuff
completed before entering into the code in the then block:
service.processStuff( arraying, parentidarg )
.then(function( data ) {
...
The caller of processStuff
waits for all doMoreStuff
invocations to complete until the caller of processStuff
enters into its then
block.
I am unsure of how to achieve this with Angular2 and Observables. I can see from these posts that to mimic promises, Observables basically just use subscribe()
instead of then()
:
Angular 1.x $q to Angular 2.0 beta
But how do I await all invocations in the forEach
loop to complete before my application can proceed?
I have been doing this with forkJoin
import {Observable} from 'rxjs/Observable'; import 'rxjs/add/observable/forkJoin'; Observable.forkJoin( this.http.get('./friends.json').map((res: Response) => res.json()), this.http.get('./customer.json').map((res: Response) => res.json()) ) .subscribe(res => this.combined = {friends: res[0].friends, customer: res[1]});
Some more info here: http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http
In RxJS v6 and later you can do this more eloquently with zip.
import { zip } from 'rxjs';
const promise1 = yourSvc.get(yourFavoriteAPI.endpoint1);
const promise2 = yourSvc.get(yourFavoriteAPI.endpoint2);
const promises = zip(promise1, promise2);
promises.subscribe(([data1, data2]) => {
console.log(data1);
console.log(data2);
});
While the result is the same, I find zip
preferable to forkJoin
since zip
is more universal and can handle new values from the observables.
Details from the rxjs documentation:
The zip operator will subscribe to all inner observables, waiting for each to emit a value. Once this occurs, all values with the corresponding index will be emitted. This will continue until at least one inner observable completes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With