MEAN 2 Multi Tenancy (Multiple collection saves that reference each other) MEAN 2 Multi Tenancy (Multiple collection saves that reference each other) mongoose mongoose

MEAN 2 Multi Tenancy (Multiple collection saves that reference each other)


This is happening because res.status() sets headers as soon as it has fired. You try to do this multiple times both when checking for errors, and then you try to set the status code again in Tenant.findById().

You end up with a flow like:

if (err) set headersset headers (again)findById()if (err) set headersset headers (again)

You have to be careful when writing out your response that you only do it at the last point in your logic flow. You can also could set up a global err handler and throw new Error() and stop the flow of logic and handle the output immediately. If you don't, your code will continue to execute even though it encountered an error.

Another tip: callbacks don't work well with returns. And although you can arrange them to work, or implement a promise architecture instead, the simplest fix (and the easiest to learn) is to make your functions all asynchronous.

Try instead something like:

tenant.save(function (err, tenant, callback) {  // add a callback param to your fn ^  if (err) {    throw({      code: 500,      title: 'An error has occured',      error: err    });  } else {  // ^ add an else statement so you don't set the headers twice   // (because res.status() sets headers)    res.status(201).json({      message: 'Tenant created',      obj: tenant    });  }  callback(err, tenant);  // call your async function instead of return,   // and pass both err and tenant as params  // (one or the other may be undefined though, if it fails/succeeds)});

... Create additional isolated functions (or even modules) for the rest of your tasks, then you can then call your function like this:

tenant.save(function(err, tenant) {  Tenant.findById(tenant._id, function(err, tenant) {    var user = new User({...})    user.save()  });});