Home > Back-end >  Sending response after forEach nodeJS
Sending response after forEach nodeJS

Time:09-17

I'm developing an API in NodeJS that will send a response only after the foreach loop has been finished with the result of each operation done inside the loop. The problem now is that the code not wait until the foreach has finished to send the respond.

Request:

  "enterpriseName": "myEnterprise",
  "channels": [
    {
      "provider": "mail",
      "contact": "11111111111",
      "configuration": [
        {
          "name" : "token",
          "value" :"1234567890"
        }
      ]
    },
    {
      "provider": "phone",
      "contact": "123456789",
      "configuration": [
        {
          "name" : "access_token",
          "value" :"987654321"
        }
      ]
    }
  ]
}

Code:

app.post('/channelEnterprise', (req, res) => {
    var output = [];
    checkEnterpriseByName(req.body.enterpriseName, knex).then((exist) => {
        if (exist) {
            req.body.channels.forEach(channel => {
                addChannel(req.body.enterpriseName, channel, knex).then((channelEnterpriseId) => {
                    output.push({'provider' : channel.provider,
                                 'Id': channelEnterpriseId[0],
                                 'result': 'ok'
                    })                  
                    res.json(output)                    
                });             
            });             
        }else{
            res.status(500).send({ error: 'Enterprise'   req.body.enterpriseName   ' does not exist. Try to create previous the enterprise and then add the channel' });
        }   
    })
})

Goal: The goal is to run res.json(output) only when the foreach has been finished with something like this:

[
    {
        "provider": "mail",
        "Id": 15,
        "result": "ok"
    },
    {
        "provider": "phone",
        "Id": 16,
        "result": "ok"
    }

]

CodePudding user response:

Instead of foreach, you should use the map function and the using Promise.all to await the map. also, use async/await to a better experience.

Try this

app.post('/channelEnterprise',async (req, res) => {
   const exist = await checkEnterpriseByName(req.body.enterpriseName, knex);
if (exist) {
  let output = [];
  await Promise.all(
    req.body.channels.map(async channel => {
      const channelEnterpriseId = await addChannel(
        req.body.enterpriseName,
        channel,
        knex
      );
      output.push({
        provider: channel.provider,
        Id: channelEnterpriseId[0],
        result: 'ok',
      });
    })
  );
  res.json(output);
} else {
  res.status(500).send({
    error:
      'Enterprise'  
      req.body.enterpriseName  
      ' does not exist. Try to create previous the enterprise and then add the channel',
  });
}
})

  • Related