Tharushi Geethma
Tharushi Geethma

Reputation: 1289

How to async an api response inside a conditional statement?

I have a function which has an API call inside an 'if' condition.When I execute that function, before completing the API response, the program moves to below code lines.That breaks the functional flow since some below codes are running before API response comes Below is my code.

 change(event: any) {

    let selectedUnitIds = event.source.value;
    let newUnitIds = this.getNewUnitIds(selectedUnitIds);

    if (newUnitIds.length !== 0) {
      this.commonServerService.getOrgUnitById(newUnitIds).subscribe(orgUnits => {
        orgUnits.forEach(unit =>
          this.unitMap.set(unit.id, unit)
        );
      });
    }


    //get selected ids' orgunits
    let selectedOrgUnits = this.getSelectedUnits(selectedUnitIds);

    // get tribes of those orgunits
    let need = this.getNeededTribes(selectedOrgUnits);
  }

The problem here is the if condition. If this API is called unconditionally, inside the subscribe method, everything is working asynchronously. Please guide me through this.

later added:- common-server.service.ts

 getOrgUnitById(id: string[]): Observable<Array<OrgUnit>>
  {
    return this.orgUnitService.findOrgUnitByIds(id);
  }

Upvotes: 0

Views: 1229

Answers (3)

Menuka Ishan
Menuka Ishan

Reputation: 5514

Use async and await as below code.

To use below code every method call change() method should be async.

 async change(event: any) {

    let selectedUnitIds = event.source.value;
    let newUnitIds = this.getNewUnitIds(selectedUnitIds);

    if (newUnitIds.length !== 0) {
      try{
        await this.getOrgUnitById(newUnitIds);
      }catch (e) {
        console.log(e);
      }
    }
    //get selected ids' orgunits
    let selectedOrgUnits = this.getSelectedUnits(selectedUnitIds);

    // get tribes of those orgunits
    let need = this.getNeededTribes(selectedOrgUnits);
  }


  getOrgUnitById(newUnitIds){
    return new Promise((resolve, reject) => {
      this.commonServerService.getOrgUnitById(newUnitIds).subscribe(orgUnits => {
        orgUnits.forEach(unit =>
          this.unitMap.set(unit.id, unit)
        );
        resolve(orgUnits)
      },error=>{
        reject(error)
      });
    })
  }

Upvotes: 0

Pardeep Jain
Pardeep Jain

Reputation: 86790

You can simply put your code in the response block, it will execute only after completion of API call then, like below -

change(event: any) {

let selectedUnitIds = event.source.value;
let newUnitIds = this.getNewUnitIds(selectedUnitIds);

if (!newUnitIds.length) {
  this.commonServerService.getOrgUnitById(newUnitIds).subscribe(orgUnits => {
    orgUnits.forEach(unit =>
      this.unitMap.set(unit.id, unit)
    );
     this.someAnotherMethod();
  });
} else {
     this.someAnotherMethod();
  }
}

someAnotherMethod() {
  let selectedOrgUnits = this.getSelectedUnits(selectedUnitIds);
  let need = this.getNeededTribes(selectedOrgUnits);
}

Upvotes: 2

the-juju
the-juju

Reputation: 176

You may use 'await' before "this.commonServerService.getOrgUnitById" You will need to declare "change" function as an async

async change(event: any) {

  let selectedUnitIds = event.source.value;
  let newUnitIds = this.getNewUnitIds(selectedUnitIds);

  if (newUnitIds.length !== 0) {
    const orgUnits = await this.commonServerService.getOrgUnitById(newUnitIds);
    orgUnits.forEach(unit =>
      this.unitMap.set(unit.id, unit)
    );
  }

  //get selected ids' orgunits
  let selectedOrgUnits = this.getSelectedUnits(selectedUnitIds);

  // get tribes of those orgunits
  let need = this.getNeededTribes(selectedOrgUnits);
}

async getOrgUnitById(id: string[]): Promise<Observable<OrgUnit[]>>
{
  return await this.orgUnitService.findOrgUnitByIds(id).toPromise();
}

Upvotes: 2

Related Questions