Nikul Panchal
Nikul Panchal

Reputation: 1673

Can't set headers after they are sent in my react api

When i call my api i am getting error 'Can\'t set headers after they are sent. can anyone please help me why i am getting this error ? Here i have added my whole code of that api, can anyone please look into it and help me what exact issue in it ?

API :

exports.getInvestments = (req, res) => {
  console.log('getInvestments');
  mysql_client.query(`SELECT * FROM connects WHERE user_id = '${req.body.user_id}' `,  (err, rows) => { 
    if(err) { 
      return res.json(err);
    }
    console.log(rows);
    let investments = [];
    if(rows.length > 0)
    {
      rows.forEach((row) => {

        const ACCESS_TOKEN = row.access_token;

        // Pull transactions for the last 30 days
        let startDate = moment()
        .subtract(30, "days")
        .format("YYYY-MM-DD");
        let endDate = moment().format("YYYY-MM-DD");

        client.getInvestmentTransactions(
          ACCESS_TOKEN,
          startDate,
          endDate,
          {
            count: 250,
            offset: 0
          },
          function(err, result) {
            if(err) 
            {
              console.log('Investment error');
              return res.json(err);
            }
            console.log("Get all investments");
            console.log(result.investment_transactions); 
            investments = investments.concat(result.investment_transactions)

           return res.json({investments});
          }
        );
      })
    }
    else
      return res.json({investments});
  });
};

Upvotes: 1

Views: 34

Answers (1)

Maciej Trojniarz
Maciej Trojniarz

Reputation: 722

Looks like you are filling up response with every row as you are using res.json() see: https://blog.fullstacktraining.com/res-json-vs-res-send-vs-res-end-in-express/

Maybe you should build up the response and sent it once?

exports.getInvestments = (req, res) => {
  console.log('getInvestments');
  mysql_client.query(`SELECT * FROM connects WHERE user_id = '${req.body.user_id}' `,  (err, rows) => { 
    if(err) { 
      return res.json(err);
    }
    console.log(rows);
    let investments = [];
  //  if(rows.length > 0) You don't need this check as forEach will be not executed if no elements in the array
  //  {
      rows.forEach((row) => {

        const ACCESS_TOKEN = row.access_token;

        // Pull transactions for the last 30 days
        let startDate = moment()
        .subtract(30, "days")
        .format("YYYY-MM-DD");
        let endDate = moment().format("YYYY-MM-DD");

        client.getInvestmentTransactions(
          ACCESS_TOKEN,
          startDate,
          endDate,
          {
            count: 250,
            offset: 0
          },
          function(err, result) {
            if(err) 
            {
              console.log('Investment error');
              return res.json(err);
            }
            console.log("Get all investments");
            console.log(result.investment_transactions); 
            investments = investments.concat(result.investment_transactions)
    // you should not use res.json function on every row as it sends response back
   //           return res.json({investments});
          }
        );
      })
//    }


    return res.json({investments});
  });
};

Upvotes: 2

Related Questions