Home > database >  How to return data from nested async function
How to return data from nested async function

Time:07-25

async getSettlementByUser(email): Promise<any> {
    let listofTerminalId = [];
    // Get current user
    let user = await this.userModel.findOne({ email: email });
    // get list of sn
    let tpeIndexes = user.bindedSn.map((item) => item);
    //list des tpes binded to current user
    let tpe = tpeIndexes.map(async (index) => {
      let list = await this.tpeModel.find({ sn: index });
      // console.log('liste des tpes', list);
      let terminalId = list.map((item) => item.terminalId);
      // console.log('terminalId', ...terminalId);
      listofTerminalId.push(...terminalId);

      console.log('listofTerminalId', listofTerminalId);
      return await listofTerminalId.map(async (item) => {
        return await this.modelSettlement
          .find({ terminalID: item })
          .then((res) => res)
          .catch((err) => console.log(err));
      });
      // console.log('settlement', settlement);
      // return settlement;
    });

    let promiseValue = await Promise.all(tpe);
    console.log('promiseValue', promiseValue);
    // // return promiseValue;
    // return tpe;
  }

OUTPUT

promiseValue [   [ Promise { <pending> } ],   [ Promise { <pending> }, Promise { <pending> } ],   [
    Promise { <pending> },
    Promise { <pending> },
    Promise { <pending> }   ] ]

I used Promise.all() to handle this nested async still get this result so How can I resolve this problem and why it shows this error

CodePudding user response:

You use Promise.all only on the outer layer of the nesting, not on the inner array of promises. You would also need to do

return Promise.all(listofTerminalId.map(async (item) => {
//     ^^^^^^^^^^^
  return this.modelSettlement
    .find({ terminalID: item })
    .catch((err) => console.log(err));
}));

However, given the listofTerminalId.push(...terminalId), it looks like you actually don't want any nesting. You may just want to

async getSettlementByUser(email): Promise<any> {
  // Get current user
  const user = await this.userModel.findOne({ email: email });

  // list des tpes binded to current user
  const tpes = await Promise.all(user.bindedSn.map(async (index) => {
    const list = await this.tpeModel.find({ sn: index });
    // console.log('liste des tpes', list);
    return list.map((item) => item.terminalId);
  }));
  const listofTerminalId = tpes.flat();
  console.log('listofTerminalId', listofTerminalId);

  const settlements = await Promise.all(listofTerminalId.map((item) => {
    return this.modelSettlement.find({ terminalID: item })
  }));
  console.log('settlements', settlements);
}

CodePudding user response:

You need to pass an array of promises to Promise.all method that means you should neither await the promises nor .then them before passing them to Promise.all.

So it might look like this:

async getSettlementByUser(email): Promise<any> {
    let listofTerminalId = [];
    let user = await this.userModel.findOne({ email: email });
    let tpeIndexes = user.bindedSn.map((item) => item);

    let tpe = tpeIndexes.map(async (index) => {
        let list = await this.tpeModel.find({ sn: index });
        let terminalId = list.map((item) => item.terminalId);
        listofTerminalId.push(...terminalId);
  
        return listofTerminalId.map((item) => {
            return this.modelSettlement
              .find({ terminalID: item })
        });
    });

    let promiseValue = await Promise.all(tpe)
    console.log('promiseValue', promiseValue);
}
  • Related