6

When i call my own api developed using node.js, connection on postgres (Sequelize) database, it's return the follow JSON:

[
  {
    "id": 1,
    "name": "Wallet Name",
    "wallet_type": "MN",
    "icon": "fa fa-bank",
    "color": "#000000",
    "credit_limit": 3000,
    "due_day": 22
  }
]

I just need, it return one more line (account_value) on each object, that's info is inside another javascript function, so it's should look as:

[
  {
    "id": 1,
    "name": "Wallet Name",
    "wallet_type": "MN",
    "icon": "fa fa-bank",
    "color": "#000000",
    "credit_limit": 3000,
    "account_value": 1200.55,
    "due_day": 22
  }
]

My current code is:

async index(req, res) {
    const wallets = await Wallet.findAll({
      where: {},
      attributes: [
        'id',
        'name',
        'wallet_type',
        'icon',
        'color',
        'credit_limit',
        'due_day',
      ],
      order: [['name', 'ASC']],
    });

    const finalObject = [];

    wallets.forEach(async wallet => {
      const currentItem = wallet.dataValues;
      const { id } = await currentItem;
      const { sum_credits } = await WalletsResume.sumCredits(id);
      const { sum_debits } = await WalletsResume.sumDebits(id);
      const sum_account_value = (sum_credits - sum_debits).toFixed(2);
      currentItem.account_value = sum_account_value;
      finalObject.push(currentItem);
      console.log(`pushed ${id}`);
    });

    console.log(`-------------------------`);
    console.log(finalObject);
    return res.json(finalObject);
  }

But, when its return a empty array:

[]

Do you can help me please?

I have no idea how to fix it (i can change all my code)

Thank you so much!

Leonardo
  • 135
  • 1
  • 2
  • 11

1 Answers1

9

Array.forEach doesn't wait for async calls. Switch to for..in/for..of or a regular for-loop.

Example using for-of

async index() {
  // Fetch wallets here

  for (const wallet of wallets) {
    const currentItem = wallet.dataValues;
    const { id } = await currentItem;
    const { sum_credits } = await WalletsResume.sumCredits(id);
    const { sum_debits } = await WalletsResume.sumDebits(id);
    const sum_account_value = (sum_credits - sum_debits).toFixed(2);
    currentItem.account_value = sum_account_value;
    finalObject.push(currentItem);
    console.log(`pushed ${id}`);
  }

  // Then continue normally
}

Example using for-in

async index() {
  // Fetch wallets here

  for (const walletIndex in wallets) {
    const currentItem = wallets[walletIndex].dataValues;
    // rest of code as above
  }

}
Abido
  • 752
  • 6
  • 18
  • Sorry, i'm just learning node. I tryied for(wallet in wallets) but its broken my code (as i seen on https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/for...in) You can tell me please, how i do it? – Leonardo Nov 16 '19 at 18:26
  • 2
    My example uses for-of not for-in – Abido Nov 16 '19 at 18:27
  • 1
    Ohhh, thank you so much!!! I'll try! :D – Leonardo Nov 16 '19 at 18:27
  • See this for difference between for-in and for-of. One sets the index of the value to the const, and the other uses the actual value. https://stackoverflow.com/a/41910537/6086851 – Abido Nov 16 '19 at 18:28
  • 1
    OMG! it's work! I'll need fix a eslint problem now, but, work very well, ty!!!! ``` iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.eslint(no-restricted-syntax) ``` – Leonardo Nov 16 '19 at 18:29
  • With for-in you have to use const currentItem = wallets[wallet].dataValues;, because wallet in this case is the index – Abido Nov 16 '19 at 18:29
  • I am not sure about eslint warning part, personally, I would have disabled it for that line. Add this one line before the for-of loop. `// eslint-disable-next-line no-restricted-syntax` – Abido Nov 16 '19 at 18:34
  • 1
    done! will be disabled - Really, thank you so much Abido, helped me a lot! I learned soo much here ;) – Leonardo Nov 16 '19 at 18:35
  • Glad to hear, you're very welcome. – Abido Nov 16 '19 at 18:36