Question

So my CRUD app at this time, does two things, keeps sending an infinite empty list. But not just that, when I try to delete something I get this error... Jump below for the api code. Also if you see anything that might contribute to an infinite list lemme know.

C:\Users\\Desktop\Todo List\node_modules\mongoose\lib\utils.js:419
        throw err;
              ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
    at ServerResponse.res.setHeader (C:\Users\\Desktop\Todo List\node_modul
es\express\node_modules\connect\lib\patch.js:63:22)
    at ServerResponse.res.set.res.header (C:\Users\\Desktop\Todo List\node_
modules\express\lib\response.js:526:10)
    at ServerResponse.res.json (C:\Users\\Desktop\Todo List\node_modules\ex
press\lib\response.js:193:36)
    at Promise.<anonymous> (C:\Users\\Desktop\Todo List\routes\api.js:45:21
)
    at Promise.<anonymous> (C:\Users\\Desktop\Todo List\node_modules\mongoo
se\node_modules\mpromise\lib\promise.js:162:8)
    at Promise.EventEmitter.emit (events.js:95:17)
    at Promise.emit (C:\Users\\Desktop\Todo List\node_modules\mongoose\node
_modules\mpromise\lib\promise.js:79:38)
    at Promise.fulfill (C:\Users\\Desktop\Todo List\node_modules\mongoose\n
ode_modules\mpromise\lib\promise.js:92:20)
    at C:\Users\\Desktop\Todo List\node_modules\mongoose\lib\query.js:1736:
26

routes api code

var Todo = require('../app/models/todos').Todo;

   exports.read = function(req, res) {

        // use mongoose to get all todos in the database
        Todo.find(function(err, todos) {

            // if there is an error retrieving, send the error. nothing after res.send(err) will execute
            if (!err)
                res.send(err)

            res.json(todos); // return all todos in JSON format
        });
    };

    // create todo and send back all todos after creation
   exports.create = function(req, res) {

        // create a todo, information comes from AJAX request from Angular
        Todo.create({text : req.body.text}, function(err, todos) {
            if (err)
                res.send(todos);

            // get and return all the todos after you create another
            Todo.find(function(err, todos) {
                if (err)
                    res.send(err)
                res.json(todos);
            });
        });

    };

    // delete a todo
   exports.delete = function(req, res) {
        Todo.remove({_id : req.params._id
        }, function(err, todos) {
            if (err)
                res.send(todos);

            // get and return all the todos after you create another
            Todo.find(function(err, todos) {
                if (err)
                    res.send(err)
                res.json(todos);
            });
        });
    };

    //Update a todo
    exports.update = function(req, res) {
        Todo.findById(req.params._id, function(err, todos){
            todos.text = req.body.text;
            console.log(todos);
            todos.save(function() {
                if (!err) {
                    res.send(todos);
                } else if (err) {
                    res.send(err);
                }

                Todo.find(function(err, todos) {
                    if (err)
                        res.send(err)
                    res.json(todos);
                });
            });
        });
    };
Was it helpful?

Solution

I usually see this error when I'm using res multiple times in my Express route by mistake. Be sure that in route handler (function) you are only using res once.

For example

app.get('/foo', doFoo);

function doFoo(req, res) {
  res.send('foo');
  res.send('bar');
}

won't work since you're trying to use res twice which internally calls res.end() if I'm not mistaken.

Edit: As it turns out, I think I see the problem in your code.

// create a todo, information comes from AJAX request from Angular
Todo.create({text : req.body.text}, function(err, todos) {
    if (err)
        res.send(todos);

    // get and return all the todos after you create another
    Todo.find(function(err, todos) {
        if (err)
            res.send(err)
        res.json(todos);
    });
});

Here, you're using res.send(todos) in the event that you receive an error from your first call to Todo.create. Assuming you do receive an error here, your code will still attempt Todo.find. Once that happens, it will then try res.json(todos) thereby firing two responses and resulting in the error that you see about not being able to set response headers after they're already sent. I think you can fix your code by using actual else statements to ensure you don't send two responses.

    Todo.create({text:req.body.text}, function(err, todos){
      if (err) {...}
      else {
        .. your else code here
      }

});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top