Nano
Nano

Reputation: 847

Routes error: Error: Can't set headers after they are sent

Well, after I read many threads about this I begin to stagnate. The error is the popular Error: Can't set headers after they are sent.

The best answer is here but, i have no repeated functions or twice executed callbacks (At least not that I know), it's just an standard base rest API.

Full trace log:

/home/nano/Dev/JS/OMI/node_modules/mongoose/lib/utils.js:413
        throw err;
              ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:689:11)
    at ServerResponse.header (/home/nano/Dev/JS/OMI/node_modules/express/lib/response.js:666:10)
    at ServerResponse.send (/home/nano/Dev/JS/OMI/node_modules/express/lib/response.js:146:12)
    at ServerResponse.json (/home/nano/Dev/JS/OMI/node_modules/express/lib/response.js:235:15)
    at Promise.<anonymous> (/home/nano/Dev/JS/OMI/app/routes/clientes.js:19:11)
    at Promise.<anonymous> (/home/nano/Dev/JS/OMI/node_modules/mongoose/node_modules/mpromise/lib/promise.js:172:8)
    at Promise.emit (events.js:95:17)
    at Promise.emit (/home/nano/Dev/JS/OMI/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
    at Promise.reject (/home/nano/Dev/JS/OMI/node_modules/mongoose/node_modules/mpromise/lib/promise.js:111:15)
    at Promise.error (/home/nano/Dev/JS/OMI/node_modules/mongoose/lib/promise.js:95:15)

Anyway, my code is simple:

index.js:

"use strict";

var express = require('express'),
    router  = express.Router();

var clientes = require('./clientes');
var items    = require('./items');

router.route('/clientes')
  .post(clientes.crear)
  .put(clientes.actualizar)
  .delete(clientes.borrar);

router.route('./items')
  .post(items.crear)
  .put(items.actualizar)
  .delete(items.borrar);

module.exports = router;

clientes.js

Note: reqHelper is my own function to go through req.body object, for now is disabled.

"use strict";

// instancias de modelos
var Cliente = require('../models/models').Cliente;
// var reqHelper = require('./util');

var clientes = {

  crear: function (req, res) {
    var nuevoCliente = {
      _id: req.body._id,
      nombre: req.body.nombre,
      direccion: req.body.direccion,
      telefono: req.body.telefono
    };

    Cliente.create(nuevoCliente, function (err, cliente) {
      if (err) res.json({status: 500, error: err});
      res.json({ status: 500, cliente: cliente });
    }); // fin Cliente.create
  }, // fin crearCliente

  actualizar: function(req, res) {
    var ci = req.body._id;

    var clienteData = {};
    // reqHelper(req.body, clienteData);

    Cliente.update({ _id: ci }, clienteData, function(err, cliente) {
      if (err) res.json({status: 500, error: err});
      res.json({ status: 200, cliente: cliente });
    }); // fin Cliente.update
  }, //fin actualizarCliente

  borrar: function(req, res) {
    Cliente.remove({ _id: req.body._id }, function(err) {
      if (err) res.json({status: 500, error: err});
      res.json({ status: 200, msg: 'Cliente borrado' });
    });
  }, // fin borrarCliente
}; // fin actions

module.exports = clientes;

items.js

"use strict";

var Item = require('../models/models').Item;
// var reqHelper = require('./util');

var items = {
  crear: function(req, res) {
    var nuevoItem = {
      _id: req.body._id,
      descripcion: req.body.descripcion,
      costo: req.body.costo,
      precioMin: req.body.precioMin,
      precioMax: req.body.precioMax,
      existencia: req.body.existencia,
      disponible:req.body.disponible
    };

    Item.create(nuevoItem, function(err, item) {
      if (err) res.json({status: 500, error: err});
      res.json({ status: 200, item: item });
    });
  }, // fin crear

  actualizar: function(req, res) {
    var itemData = {};
    var itemId = req.body._id;  

    // reqHelper(req.body, itemData);

    Item.update({_id: itemId}, itemData, function(err, item) {
      if(err) res.json({status: 500, error: err});
      res.json({status: 200, token: item});
    }); // fin Item.update
  }, // fin actualizar

  borrar: function(req, res) {
    Item.remove({_id: req.body._id}, function(err){
      if(err) res.json({status: 500, error: err});
      res.json({ status: 200, msg: 'Item removido' });
    });
  }, // fin borrar
}; // fin items

module.exports = items;

Upvotes: 3

Views: 13005

Answers (2)

Oleksandr T.
Oleksandr T.

Reputation: 77482

As I see you have error in this function

  crear: function (req, res) {
    var nuevoCliente = {
      _id: req.body._id,
      nombre: req.body.nombre,
      direccion: req.body.direccion,
      telefono: req.body.telefono
    };

    Cliente.create(nuevoCliente, function (err, cliente) {
      if (err) res.json({status: 500, error: err});
      res.json({ status: 500, cliente: cliente });
    }); // fin Cliente.create
  }, // fin crearCliente

And I think Cliente.create returns err, so you need change this function like this

      if (err) {
        return res.json({status: 500, error: err});
      }
      res.json({ status: 500, cliente: cliente });

Upvotes: 4

loganfsmyth
loganfsmyth

Reputation: 161457

All of your routes call res.json twice.

if (err) res.json({status: 500, error: err});
res.json({ status: 200, msg: 'Cliente borrado' });

has no return or else. You probably mean

if (err) res.json({status: 500, error: err});
else res.json({ status: 200, msg: 'Cliente borrado' });

or

if (err) return res.json({status: 500, error: err});
res.json({ status: 200, msg: 'Cliente borrado' });

Since you are calling it twice, you start sending your data, and then the second call tries to send the application/json header again, which is not allowed.

Upvotes: 8

Related Questions