Home > Software engineering >  How to only execute the res.redirect after the for() loop ends
How to only execute the res.redirect after the for() loop ends

Time:11-22

I have the following post route:

app.post("/respostaAprovChamado", function(req, res){
    if(req.isAuthenticated()){
      for(let i = 0; i < req.body.indiceAprov; i  ){
        Chamado.updateMany(
          {"_id": req.body.idChamadoPost, ["listaAprovadores."   i   ".nome"]: req.user.realNome},
          {
            $set: {["listaAprovadores."   i]: [{nome: req.user.realNome}, {status: req.body.respostaAprov}]}
          },
          {
              returnNewDocument: true
          }
      , function( error, result){
        if(error){
          res.send(error)
        } else{
          res.redirect('/aprovChamados')
        }
      })};
    }else{
      res.redirect('/login')
    }
})

I get the following error because of the for() loop trying to redirect multiple times:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

The route works. The update is made in the database, but i need to restart Node every time because of this error. I need the for() loop to iterate over the objects inside "listaAprovadores" array.

Maybe async functions do the trick, but i'm new to JavaScript and Node. What can i do?

CodePudding user response:

Issues with your code

1- you're using updateMany to update one element, use updateOne

2- trying to send response in a for loop which is incorrect

3- an advice: don't use callbacks use either promises or async/await (which is another syntax for promises)

try the following

app.post("/respostaAprovChamado", function (req, res) {
  if (req.isAuthenticated()) {
    const updatePromises = [];
    for (let i = 0; i < req.body.indiceAprov; i  ) {
      updatePromises.push(Chamado.updateOne(
        { "_id": req.body.idChamadoPost, ["listaAprovadores."   i   ".nome"]: req.user.realNome },
        {
          $set: { ["listaAprovadores."   i]: [{ nome: req.user.realNome }, { status: req.body.respostaAprov }] }
        },
        {
          returnNewDocument: true
        }))
    };
    Promise.all(updatePromises)
      .then(result => res.redirect('/aprovChamados'))
      .catch(error => res.send(error))
  } else {
    return res.redirect('/login')
  }
})

or using async/await

app.post("/respostaAprovChamado", async function (req, res) {
  try {
    if (req.isAuthenticated()) {
      const updatePromises = [];
      for (let i = 0; i < req.body.indiceAprov; i  ) {
        updatePromises.push(Chamado.updateOne(
          { "_id": req.body.idChamadoPost, ["listaAprovadores."   i   ".nome"]: req.user.realNome },
          {
            $set: { ["listaAprovadores."   i]: [{ nome: req.user.realNome }, { status: req.body.respostaAprov }] }
          },
          {
            returnNewDocument: true
          }))
      };
      await Promise.all(updatePromises)
      return res.redirect('/aprovChamados')
    } else {
      return res.redirect('/login')
    }
  } catch (error) {
    return res.send(error)
  }
})
  • Related