In a controller I am using promises because I perform multiple queries and I want to avoid having a multitude of callbacks, if you do not find a value must send a message to the client and not pass to the next promise.
This is my code:
var body = req.body;
var params = req.params;
var queryParams = req.query;
var origin = req.get('source-type') || req.get('user-agent');
var orderData = new orderInterface(origin);
orderData.setOrigin(origin);
var historyData = new historyInterface();
usersModel
.findOne({ 'shopcart._id' : body.shopcart }, { 'password': false, 'credit': false })
.exec()
.then(function(user){
var address = body.address;
orderData.setUser(user.toObject());
if(_.isObject(address)){
address.user = user._id;
return new addressModel(address).save();
}else{
return addressModel.findOne({ '_id': address }).exec();
}
})
.then(function(address){
orderData.setAddress(address);
if (_.isEmpty(address.latitude) || _.isEmpty(address.longitude)){
res.status(200).json(message.custom('No have coordinates in address'));
}else{
return establishmentsModel
.findCoordinates([ address.latitude, address.longitude ])
.populate('items.product')
.exec();
}
})
.then(function(establishments){
var shopcart = orderData.shopcart;
if(_.isEmpty(shopcart) || _.isEmpty(establishments)){
var msn = 'Establishments not have coverage';
if(_.isEmpty(shopcart)){
msn = 'problem with the shopcart';
}
res.status(200).json(message.custom(msn));
}else{
shopcart.products.forEach(function(product){
if(product.items){
var item = establishments.items.id(product.items);
if(item){
orderData.addProducts(item, product.quantity);
establishments.items[item.__index].buy += product.quantity;
establishments.items[item.__index].quantity -= product.quantity;
}else{
res.status(200).json(message.custom('produc outoff stablishments' + product.string()));
}
}else{
res.status(200).json(message.custom('product without item' + product.string()));
}
});
orderData.setEstablishments(establishments);
return establishments.save();
}
})
.then(function(establishments){
var coupon = orderData.shopcart.coupon;
var options = {
code : coupon || '',
userId : orderData.user._id
};
return referralsModel.searchAndUse(options);
})
.then(function(result){
var options = {};
if(result.referrals){
orderData.setDiscount(result.discount);
historyData.setCoupon(result.referrals);
}else{
options.code = result.coupon;
}
options.establishments = orderData.establishments._id;
options.items = orderData.items;
return couponsModel.searchAndUse(options);
})
.then(function(result){
if(result.promotion){
historyData.setCoupon(result.promotion);
}
else if(_.isEmpty(result)){
historyData.setItems(orderData.items);
historyData.setCoupon(result.coupon);
}
if(result.discount){
historyData.setDiscount(result.discount);
orderData.setDiscount(result.discount);
}
orderData.addState('', new Date());
orderData.addPay(body.pay);
return new ordersModel(orderData.get('save')).save();
})
.then(function(order){
historyData.setTime(orderData.order.create);
historyData.setUser(orderData.user._id);
if(historyData.get().save !== 0){
orderData.setId(order._id);
return historyModel.save(historyData.get());
}else{
if(params.userId){
orderData.setId(order._id);
order = orderData.get('send');
}
res.status(201).json(order);
}
})
.then(function(history){
var orderSend = orderData.get('send');
res.status(201).json(orderSend);
})
.catch(function(err){
console.log(err);
next(err);
});
When I run the test he sends me the following error twice:
[Error: Can't set headers after they are sent.]
[Error: Can't set headers after they are sent.]