0

I'm fairly new to Express and React and I am having some issues. I have created an API for multiple table insertion and I am passing an object which contains an array from React client-side My data is getting stored inside the tables but after that, when I am trying to send the response as res.send() it gives me an error as cannot set headers once they are sent to the client.

Below is my API file for POST req

enter code here
router.post("/",function(req,res){
console.log(req.body.expense);
console.log(req.body.expenseListArr);
budget_id=req.body.expense.budget_id;
expenseListArr=req.body.expenseListArr;
conn.query("insert into tblexpense(budget_id,status) values('" +budget_id+"',0)",function(Inserterr){
    if(!Inserterr){
        conn.query("select max(expense_id) expense_id from tblexpense",function(Displayerr,result){
            if(!Displayerr){
                expense_id=result[0].expense_id;
                expenseListArr.forEach(function(expenseList) {
                    conn.query("insert into tblexpense_list(expense_id,category_id,amount,description,status) values('" +expense_id+"','"+expenseList.category_id+"','"+expenseList.amount+"','"+expenseList.description+"',0)",function(MultiInserterr){
                        if(MultiInserterr){
                            console.log("right");
                            return res.json({msg:"asd"});
                        }
                        else{
                            console.log("wrong");
                            console.log(MultiInserterr);
                        }
                    });
                });
            }
            else{
                console.log("wrong");
                console.log(Displayerr);
            }
        });
    }
    else{
        console.log("wrong");
        console.log(Inserterr);
    }
});

});

Matthew Kwong
  • 2,548
  • 2
  • 11
  • 22

1 Answers1

0

Express res.json or res.send can only send response once. You are trying to return a res.json again and again in a loop. That is why it throws an exception. The best way to do this would be to extract the data from loop in an array first then, return at last when the loop is executed.
Here's an example of how you can do this.

router.post("/",function(req,res){
console.log(req.body.expense);
console.log(req.body.expenseListArr);
budget_id=req.body.expense.budget_id;
expenseListArr=req.body.expenseListArr;
let resultArr = [];
conn.query("insert into tblexpense(budget_id,status) values('" +budget_id+"',0)",function(Inserterr){
    if(!Inserterr){
        conn.query("select max(expense_id) expense_id from tblexpense",function(Displayerr,result){
            if(!Displayerr){
                expense_id=result[0].expense_id;
                expenseListArr.forEach(function(expenseList) {
                    conn.query("insert into tblexpense_list(expense_id,category_id,amount,description,status) values('" +expense_id+"','"+expenseList.category_id+"','"+expenseList.amount+"','"+expenseList.description+"',0)",function(MultiInserterr){
                        if(MultiInserterr){
                            console.log("right");
                            resultArr.push({msg:"your message or result object"});
                        }
                        else{
                            console.log("wrong");
                            console.log(MultiInserterr);
                        }
                    });
                });
                return res.json(resultArr);
            }
            else{
                console.log("wrong");
                console.log(Displayerr);
            }
        });
    }
    else{
        console.log("wrong");
        console.log(Inserterr);
    }

});

You can either do this or return resultArr outside the callback. And your route will work just fine.

For a detailed explaination about this, You should check out this answer.