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.

5
  • You can only send back one response to the browser (be it res.send(), res.end(), res.sendFile(), res.json() or any other). You can't have that inside a .forEach(). Commented Feb 28, 2020 at 14:34
  • how can i send an array at once then ? Commented Feb 28, 2020 at 14:35
  • Well, build an array, then send it once... Commented Feb 28, 2020 at 14:36
  • With Mongoose, you'd be like Model.find().lean().exec( docs => res.json(docs)) Commented Feb 28, 2020 at 14:38
  • Posted a complete answer Commented Feb 28, 2020 at 14:42

2 Answers 2

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);
        }
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

still having the same error even after sending a single response , please watch the post content update , thanks .
This is still the same issue, you are sending a response for each employee you have. You must send one and only one response.
Look at the edit i made. I hope it will work for you
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))

4 Comments

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
Yes, it should be cursor.forEeach( function (doc). Fixed
still having the same issue ! empty array sent to the browser .
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.