angularrxjsobservablesubscribeconcatmap

RxJs Angular multiply sync http webcalls


I have to make multiply sync webcalls, one after another if it's status is ok.

Horrible, but working code:

        this.api.post1().subscribe((data: any) => {
          if (data.status== 'OK') {

            this.api.post2().subscribe((data: any) => {
              if (data.status== 'OK') {

                this.api.post3().subscribe((data: any) => {
                  if (data.status== 'OK') {

                    this.api.post4().subscribe((data: any) => {
                      if (data.status == 'OK') {
                        // Do something
                      }else{
                        console.log('error: ' + data.status);
                      }
                    });

                  }else{
                    console.log('error: ' + data.status);
                  }
                });

              }else{
                console.log('error: ' + data.status);
              }
            });

          }else{
            console.log('error: ' + data.status);
          }
        });

I try use concatMap

const post1$ = this.api.post1();
const post2$ = this.api.post2();
const post3$ = this.api.post3();
const post4$ = this.api.post4();

from([post1$, post2$, post3$, post4$]).pipe(
      concatMap(a => a)
    ).subscribe(res => console.log(res));

But I need to check is each answer ok here. Is there a beautiful solution to this?


Solution

  • I would recommend you to use RxJS's pipeable operators, and handling the errors along the pipe chain. You can make use switchMap for the chaining of the requests, as well as using throwError to end the chain and emit error observables.

    this.api.post1()
      .pipe(
        switchMap(res => {
          if (data.status === 'OK') {
            return of(this.api.post2());
          } else {
            console.log('error: ' + data.status);
            return throwError('Twos are bad');
          }
        }),
        switchMap(res => {
          if (data.status === 'OK') {
            return of(this.api.post3());
          } else {
            console.log('error: ' + data.status);
            return throwError('Twos are bad');
          }
        }),
        switchMap(res => {
          if (data.status === 'OK') {
            return of(this.api.post4());
          } else {
            console.log('error: ' + data.status);
            return throwError('Twos are bad');
          }
        }),
    ).subscribe(res => {
      console.log(res);
      // do the rest here
    }, error => {
      // handle error
    })