Search code examples
javascriptnode.jsangularangular-materialmat-table

How to handle two api calls in Angular Subsink?


I am making an api call within angular subsink as follows:

import {SubSink} from 'subsink';
...
...
async clickButton() {
    for (let i = 0; i < this.Id.length; i++) {
        const hostId = await this.serviceA.Status(this.hostName[i]);
        this.subs.sink = this.serviceB.createDbEntry(hostId))
            .subscribe(s => {
                if (i === this.Id.length - 1) {
                    this.dialog.close();
                }
            });
    }
}

Here this.Id is of type any

Now I want to make another api call after the successful completion of this.serviceB.createDbEntry(hostId) And, I am doing it by adding another subs.subsink as below:

import {SubSink} from 'subsink';
...
...
async clickButton() {
    for (let i = 0; i < this.Id.length; i++) {
        const hostId = await this.serviceA.Status(this.hostName[i]);
        this.subs.sink = this.serviceB.createDbEntry(hostId))
            .subscribe(s => {
                if (i === this.Id.length - 1) {
                    this.dialog.close();
                }
            });
        this.subs.sink = this.serviceC.runRetry(hostId))
            .subscribe(s => {
                if (i === thisserverId.length - 1) {
                    this.dialog.close();
                }
            });             
    }
}

This is closing the dialog box after this.serviceB.createDbEntry(hostId)) and not calling this.serviceC.runRetry(hostId))


Solution

  • With Using Observables

    You can use forkJoin and switchMap operator of Rxjs.

    Check documentation of forkjoin and also

    Check documentation of switchMap

    With using the operators you can rewrite your code like

    forkJoin(this.hostName.slice(0, this.Id.length).map(hostName => {
      return this.serviceA.Status(hostName).pipe(
        switchMap(hostId => this.serviceB.createDbEntry(hostId).pipe(map((dbEntry) => ({dbEntry, hostId})))),
        switchMap(resp => this.serviceC.runEntry(resp.hostId))
      )
    })).subscribe(() => this.dialog.close());
    

    With Using Promises

    Promise.all(this.hostName.slice(0, this.Id.length).map(hostName => 
          this.serviceA.Status(hostName)
          .then(hostId => this.serviceB.createDbEntry(hostId).then(() => hostId))
          .then(hostId => this.serviceC.runEntry(hostId))
          )).then(() => this.dialog.close())