nehalist nehalist - 6 months ago 10
Node.js Question

Can't set headers after they are sent without additional res statements

Using sailsjs v0.12.1

index: function(req, res) {
Customer.find().populate('projects').exec(function(err, customers) {
customers.forEach(function(customer, index) {
customer.projects.forEach(function(project, index) {
// Find project contributors and attach to project
ProjectContributor.find({
project: project.id
}).populate('user').exec(function(err, contributor) {
project.contributor = contributor;

return res.json(customers);
});
});
});
});
}


This triggers
Error: Can't set headers after they are sent.
. The interesting thing here is that this error isn't triggered always - everything worked fine ~30 minutes ago.

There's no other
return res.x
statement anywhere else in this controller.

Answer

You need to install the async library first.

npm install async --save

Then you can use the following code

var async = require('async');
// ...
// ...
Customer.find().populate('projects').exec(function(err, customers) {
    var tArray = [];
    async.each(customers, function(customer, cb) {
        var aCustomer = customer; // might want to deep copy it?
        aCustomer.projects = [];
        async.each(customer.projects, function(project, projectCB) {
            ProjectContributor.find({
                project: project.id
            }).populate('user').exec(function(err, contributor) {
                project.contributor = contributor;
                aCustomer.projects.push(project);
                projectCB();
            });
        }, function projectsDone(err) {
            tArray.push(aCustomer);
            cb();
        });
    }, function done(err) {
        return res.json(tArray);
    });
});

I haven't tested the code, but it should work just fine.