2

I got this helper function:

const Account = require('../models/account');

exports.sendInvites = (accountIds, invite, callback) => {

  if (!accountIds) {

    callback('No account ids provided', null, null);

    return;
  }

  accountIds.forEach((id) => {
    Account.findOneAndUpdate({_id: id}, {$push: {organisationInvites: invite}}, callback);
  });
};

Then I have this route:

router.post('/organisations', auth.verifyToken, (req, res, next) => {

  const organisation = new Organisation({
    name: req.body.name,
    email: req.body.email,
    admins: [req.body.createdBy],
    createdBy: req.body.createdBy
  });

  organisation.save((err, organisation) => {

    if (err) {

      return res.status(500).json({
        error: err,
        data: null
      });
    }

    organisationUtils.sendInvites(req.body.invites, {
      inviter: req.body.createdBy,
      organisation: organisation._id
    }, (err, account, response) => {

      if (err) {

        return res.status(500).json({
          error: err,
          data: null
        });
      }

      res.json({
        error: null,
        data: organisation
      });
    });
  });
});

I get a Error: Can't set headers after they are sent. error for the

res.json({
  error: null,
  data: organisation
});

part but I can't understand why this is happening. I tried looking at the accepted answer here Error: Can't set headers after they are sent to the client, did some digging but couldn't find any specific reason still what's happening in my particular example above. Any ideas?

Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175

2 Answers2

2

You are calling the callback multiple times, and so res.json multiple times. Gather the data from all database request then perform an unique res.json.

accountIds.forEach((id) => {
    Account.findOneAndUpdate(
                              {_id: id}, 
                              {$push: {organisationInvites: invite}},
                               callback,
                            );
});

Something like :

    var allData = [];
    var nbRequestDone = 0;

    var waitAllCallback = function (data, err) {
       if (err) {
         callback(err);

         nbRequestDone = accountIds.length;

         return;
       }

       nbRequestDone += 1;

       allData.push(data);

       if (nbRequestDone === accountIds.length) {
         callback(false, allData);
       }
    };

    accountIds.forEach((id) => {
      Account.findOneAndUpdate(..., waitAllCallback);
    });
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
0

this video covers the Error regarding "Error: Can't set headers after they are sent". https://www.youtube.com/watch?v=rKTlakY8j2M

In summary of the video, this error shows up when you have an extra callback in your code. Hope this helps. Been struggling with this one too for quite some time.

  • 2
    While this link may answer the question, it is better to include the [essential parts of the answer](https://meta.stackexchange.com/a/8259) here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – adiga Mar 28 '19 at 07:22