Reputation: 778
I have an array of HTTP requests that I need to fire in certain order, but if any of the previous one fails then none of the following ones is going to be executed.
How can I achieve that?
What's the best approach?
I need something like:
let failed: boolean = false;
payloadArray.forEach(payload => {
if (!failed) {
http.post(this.url, payload, this.options)
.map((res: Response) => {
return res.json;
})
.catch((error: any) => {
failed = true;
Observable.throw(error.json().error || 'Server error')
});
}
}
Upvotes: 3
Views: 1200
Reputation: 54811
This would require an Observable creator that merged the emitted values, but only subscribed in sequence after each completed. I don't think there is anything like that in the RxJs library.
I did write a factory method that I think would yield what you want:
public sequence(requests: Array<Observable<Response>>): Observable<Response[]> {
return Observable.create((observer) => {
const output = [];
function executeHttp() {
const request = requests.pop();
if (request) {
request.take(1).subscribe((value) => {
output.push(value);
executeHttp();
}, (ex) => {
observer.error(ex);
});
} else {
observer.next(output);
observer.complete();
}
}
executeHttp();
});
}
Note that I added a take(1)
operator to the HTTP observables. This was done to have the HTTP observables destroyed after they yield a response. So that you don't have to call unsubscribe. You can use take(1)
or first()
which do the same thing, but they work differently when there is nothing emitted.
If you find operators that do what you want. Please let me know.
Upvotes: 3