Angular2 - How to bind asynchronous HTTP requests and stop if fails

I have an array of HTTP requests that I need to run in a specific order, but if any of the previous ones fail, none of the following will be executed.

  • How can I achieve this?

  • 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')
       });
     }
  }

      

+3


source to share


2 answers


This would require an Observable creator that concatenates the emitted values, but only subscribes sequentially after each completion. I don't think there is anything like this in the RxJs library.

I wrote a factory method that I think will give 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 have added an operator take(1)

for HTTP observables. This was done to destroy the HTTP observables after receiving the response. To prevent you from unsubscribing. You can use take(1)

or first()

, which do the same, but they work differently when nothing is emitted.

If you find operators that do what you want. Please let me know.

+3


source


if you want to send multiple HTTP requests use ForkJoin

. since for you the question the Http module handles both success and errors in the response



let failed: boolean = false;
let sampleArr = [];

payloadArray.forEach(payload => {
    if (!failed) {
        sampleArr.push(this.http.post(this.url, payload, this.options))
    }
})

Observable.forkJoin(sampleArr).subscribe(
    (data) => this.data = data, 
    (err) => Observable.throw(err.json().error || 'Server error')

); 

      

-1


source







All Articles