Reputation: 13
I have looked at various answers on the site, but i don't seem to be able to find a solution. I am making two almost identical requests from one page, one of them is made every 15 minutes and the other one is done on a click. The one that is called periodically is the first one to be called and the code is as follows:
var express = require('express');
var router = express.Router();
var mongodb = require('mongodb');
var assert = require('assert');
router.get('/', function(req, res, next) {
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
get_number(db,function(user_res){
return res.json(user_res);
db.close();
})
}
});
});
function get_number(db,cb)
{
var collection = db.collection('result');
collection.aggregate(
{ $group:
{ _id: {'number':'$number','name':'$name'}, total: { $sum: 1 } }
},
{ $sort : { total : -1 } },
{ $limit : 10 },
function (err, res) {
if (err) console.log(err);
cb(res);
}
);
}
module.exports = router;
The problem is every time i call the second page, onclick event, then i get the data but then the error - "Can't set headers after they are sent" is displayed.
The code for the second page is as follows:
var express = require('express');
var router = express.Router();
var mongodb = require('mongodb');
var assert = require('assert');
router.get('/:number', function(req,res,next){
var MongoClient = mongodb.MongoClient;
id = parseInt(req.params.number);
var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
get_comments(db,function(user_res){
res.json(user_res);
db.close();
})
}
});
});
var get_comments = function(db, callback) {
var cursor = db.collection('result').find({ 'number': id });
cursor.each(function(err, doc) {
assert.equal(err, null);
callback(doc);
if (doc != null) {
callback(doc);
} else {
callback();
}
});
};
module.exports = router;
Both the pages are being called from one page only. So, any suggestions as to where i might be going wrong.
Upvotes: 0
Views: 407
Reputation: 2474
The problem lies in he cursor.each
section. You are calling the callback for every item which in turn sends individual response for all item in the connection. But res.json can be used only once for a request. You must restructure your code either to send all data at once or send response using res.write
and manually end the response after sending all data by caling res.end()
Try changing the get_comments
to the following. You will have to edit the client that uses this data because it will be receiving an array of objects.
var get_comments = function(db, callback) {
var cursor = db.collection('GameScore').find({ 'number': id });
var docArr = [];
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
docArr.push(doc);
}
cursor.hasNext().then(function(){
callback(docArr);
});
});
};
In this case the docs returned from find query is iterated one by one and pushed to a temporary array. Then curosr.hasNext()
checks if there is any more remaining objects in find query. Then the callback is called once with the entire array.
Upvotes: 2