DarioN1
DarioN1

Reputation: 2552

Nested functions calls not working ( code flow issue )

I'm having some problem with my code:

The problem is this:

If the param.qtamodificata == false, the code runs properly, but If params.qtamodificata == true ( and it call getQuantities function ) it return "undefined" because of the async call...

I need to set the code flow in a sync way in order to return the result only after all the procedure has finished to process...

How to fix it ?

Thanks to support

getOrderRow

public getOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    return Observable.fromPromise(this._WebDBService.sysConfigurazione.toArray().then(
      data => {

        var art = JSON.parse(data[0].ordinidatajson).filter(
          function(itm,index){
            return itm.codart.v === params.codart;
          }
        );

        res.headers = JSON.parse(data[0].ordiniheaderjson);

        if(params.qtamodificata == true)
        {
          this.getQuantities(art[0].codart.v,null,params.udmmodificata, params['qtaord'+ params.udmmodificata]).subscribe(
            qtys =>{
                  art[0].qtaord1.v = qtys.dqta1;
                  art[0].qtaord2.v = qtys.dqta2;
                  art[0].qtaord3.v = qtys.dqta3;

                  res.data = art[0];

                  return res;
                }
              );          
        }
        else
        {
          res.data = art[0];
          return res;
        }                         
      }
    ));
  }

getQuantities

public getQuantities(codart: string, codvar: string, idqta: number, qta: number): Observable<any>{

    return Observable.fromPromise(this._WebDBService.tbArticoli.where({codart: codart}).toArray().then(
      data => 
      {
        console.log('getQuantities');               

        var qtys = {
          dqta1: 0,
          dqta2: 0,
          dqta3: 0
        }

        var a = data[0];

        switch (idqta) {
          case 1:
            qtys.dqta1 = +qta;
            if (a.rapudm12 > 0 && a.codudm2)
              qtys.dqta2 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 2:
            qtys.dqta2 = +qta;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 3:
            qtys.dqta3 = +qta;
            if (a.rapudm23 > 0 && a.codudm2)
              qtys.dqta3 = qta / a.rapudm23;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            break;
        }
        return qtys;

      }));    
  }

Function Call

this.orderService.getOrderRow(params, 'test')
          .subscribe(list => {
            console.log('onlineorder3');
            console.log(list);
            console.log('onlineorder3');
}

Upvotes: 3

Views: 74

Answers (2)

DarioN1
DarioN1

Reputation: 2552

I solved my problem by using forkJoin and by rewriteing the getOrderRow method:

 public getOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    return Observable.forkJoin(
      Observable.fromPromise(this._WebDBService.sysConfigurazione.toArray()),
      this.getQuantities(params.codart, null, params.udmmodificata, params['qtaord' + params.udmmodificata])
    ).map((
      data: any[]) => {      

        var o = {headers: [], data:[]}

        var art = JSON.parse(data[0][0].ordinidatajson).filter(
          function (itm, index) {
            return itm.codart.v === params.codart;
          }
        );

        art[0].qtaord1.v = data[1].dqta1;
        art[0].qtaord2.v = data[1].dqta2;
        art[0].qtaord3.v = data[1].dqta3;

        o.headers = JSON.parse(data[0][0].ordiniheaderjson);
        o.data = art[0];

        return o;
      }
    );

Upvotes: 0

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250036

I see you convert Promisses to Observables, in this case I think Promises in conjunction with async/await will make your code both easier to sequence correctly and also easier to read and understand . A version would be:

public async getOrderRow(params): Promise<any> {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    var data = await this._WebDBService.sysConfigurazione.toArray();
    var art = JSON.parse(data[0].ordinidatajson).filter(
        function (itm, index) {
            return itm.codart.v === params.codart;
        }
    );

    res.headers = JSON.parse(data[0].ordiniheaderjson);

    if (params.qtamodificata == true) {
        let qtys = await this.getQuantities(art[0].codart.v, null, params.udmmodificata, params['qtaord' + params.udmmodificata]);

        art[0].qtaord1.v = qtys.dqta1;
        art[0].qtaord2.v = qtys.dqta2;
        art[0].qtaord3.v = qtys.dqta3;

        res.data = art[0];

        return res;

    }
    else {
        res.data = art[0];
        return res;
    }
}

public async getQuantities(codart: string, codvar: string, idqta: number, qta: number): Promise<any> {

    let data = await this._WebDBService.tbArticoli.where({ codart: codart }).toArray();
    console.log('getQuantities');
    var qtys = {
        dqta1: 0,
        dqta2: 0,
        dqta3: 0
    }
    // ... Omitted for brevity
    return qtys;
}

Note I used Promise<any> for the return types, I would recommend instead of any you use a type that actually describes the result. For example for getQuantities the return value should probably be Promise<{dqta1:number, dqta2:number, dqta3:number }>.

Upvotes: 1

Related Questions