iGyan.Org iGyan.Org - 3 months ago 6
Javascript Question

Getting Error with express : Can't set headers after they are sent

I am creating express app and in the router I am going to fetch data from the mongodb. here is my code

router.get('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
db.collection('school').find({}).toArray(function(err, doc) {
assert.equal(null, err);
assert.ok(doc != null);
res.render('index', { title: 'iGyan.org', schools: doc});
});

db.collection('students').find({}).toArray(function(err, doc) {
assert.equal(null, err);
assert.ok(doc != null);
res.render('index', { title: 'iGyan.org',students: doc});
});
db.close();
});
});


When I run the code and opens a url in browser, it gives me error on the console stating

Error: Can't set headers after they are sent.


I have seen almost all suggested question asked on stack overflow, but cant get help out of it.

I know the error is because I am rendering the res two time in the function but do not know how to overcome the situation.

Answer

You could render the response only once like this:

router.get('/', function(req, res, next) {
    var data = {};
    MongoClient.connect(url, function(err, db) {
        db.collection('school').find({}).toArray(function(err, doc) {
            assert.equal(null, err);
            assert.ok(doc != null);
            data.schools = doc;
        });

        db.collection('students').find({}).toArray(function(err, doc) {
            assert.equal(null, err);
            assert.ok(doc != null);
            data.students = doc;
        });
        db.close();

        // only rendering once, inside the async mongo callback.
        // res.render will call res.end() and end the response process
        res.render('index', {
            title: 'iGyan.org',
            students: data.students,
            schools: data.schools
        });
    });

});