0

I am fetching data from a MongoDB database then putting it in a cursor to send that as a Node.js response.

var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';
/* GET users listing. */
router.get('/', function(req, res, next) {
  //res.send('respond with a resource');
  MongoClient.connect(url, function(err, db) {
    var cursor = db.collection('Employee').find();
    cursor.each(function(err, doc) {

      console.log(doc);
      arrayres = doc ;
     res.send(doc);

    });
    db.close();
  });
});

module.exports = router;

It sends only the first record then I get this error:

Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client
    at ServerResponse.removeHeader (_http_outgoing.js:528:11)
    at ServerResponse.send 

Notice: I get this error only when there are multiple records to send as response.

Cik
  • 17
  • 5
CoderTn
  • 985
  • 2
  • 22
  • 49

2 Answers2

1

You are sending the response twice. Which is impossible ( look at Why can't we do multiple response.send in Express.js? )

  res.send('respond with a resource');

Here and

res.send(arrayres);

Here.

Here is a working example based on jeremy's answer :

router.get('/', function (req, res, next) {
    MongoClient.connect(url, function (err, db) {
        var cursor = db.collection('Employee').find();

        let employees = []
        const pushData = async () => {
            cursor.forEeach( function (doc) {
                employees.push(doc);
            });
        }
        const sendResponse = async () => {
            await pushData();
            res.json(employees);
        }
    });
});
0

You can only send back one response to the browser (be it res.send(), res.end(), res.sendFile(), res.json() or any other). So, you can't have that inside a .forEach().

First, build an array, then send your data back once.

router.get('/', function (req, res, next) {
    MongoClient.connect(url, function (err, db) {
        var cursor = db.collection('Employee').find();

        let employees = []

        cursor.forEeach( function (doc) {
            employees.push(doc);
        });

        res.json(employees);
    });
});

Or with Mongoose :

Employee.find().lean().exec( (err,docs) => res.json(docs))
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
  • thank you @jeremy Thille for your answer but i actually sending an empty array "[ ]" i think there is a problem with push into the array – CoderTn Feb 28 '20 at 14:48
  • Yes, it should be `cursor.forEeach( function (doc)`. Fixed – Jeremy Thille Feb 28 '20 at 14:51
  • still having the same issue ! empty array sent to the browser . – CoderTn Feb 28 '20 at 15:07
  • Well that's a different problem. How to build the data you send back is something else. I don't use Mongo's native driver, so I don't know how to use `cursor`. Mongoose makes your life so much easier :) Anyway you get the idea, you can't use `res.end()` more than once. – Jeremy Thille Feb 28 '20 at 15:25