Can't set headers after they are sent. NodeJS - javascript

Following is my code where i first authenticate if the users are present in the group and if present push the accounts into the array and save. This is done via a POST request on /addaccount.
groupRouter.post('/addaccount', Verify.verifyOrdinaryUser, function(req, res, next) {
Groups.findById(req.body.group, function(err,group) {
if (err) next(err);
var checkUser = function(user) {
for(var i=0; i<group.users.length; i++)
{
if(group.users[i]==user)
return true;
}
return false;
}
if(checkUser(req.decoded._doc._id)){
User.find({mobile:{$in:req.body.split}}, function(err, users) {
if(err) next(err); var flag = true;
if(users.length == req.body.split.length ) {
for(var i=0; i<users.length; i++) {
if(!checkUser(''+users[i]._id)) {
flag = false;
break;
}
}
if(flag) {
var myObject = {};
myObject.amount = req.body.amount;
myObject.by = req.decoded._doc._id;
myObject.split = req.body.split;
group.accounts.push(myObject);
group.save(function (err, groups) {
if(err) next(err);
console.log('Added entries');
res.json(groups);
})
}
else
res.end('All users not in the group');
}
else
res.end('Split users do not exist');
})
}
else
res.end('No Permission');
})
})
Now when I input an array of users and try to push an object and save via the
code below:
if(flag) {
var myObject = {};
myObject.amount = req.body.amount;
myObject.by = req.decoded._doc._id;
myObject.split = req.body.split;
group.accounts.push(myObject);
group.save(function (err, groups) {
if(err) next(err);
console.log('Added entries');
res.json(groups);
})
}
I get an error saying Error: Can't set headers after they are sent. as shown below.
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11)
at ServerResponse.header (D:\Ionic\PocketBuddies\node_modules\express\lib\response.js:718:10)
at ServerResponse.send (D:\Ionic\PocketBuddies\node_modules\express\lib\response.js:163:12)
at done (D:\Ionic\PocketBuddies\node_modules\express\lib\response.js:957:10)
at Object.exports.renderFile (D:\Ionic\PocketBuddies\node_modules\jade\lib\index.js:374:12)
at View.exports.__express [as engine] (D:\Ionic\PocketBuddies\node_modules\jade\lib\index.js:417:11)
at View.render (D:\Ionic\PocketBuddies\node_modules\express\lib\view.js:126:8)
at tryRender (D:\Ionic\PocketBuddies\node_modules\express\lib\application.js:639:10)
at EventEmitter.render (D:\Ionic\PocketBuddies\node_modules\express\lib\application.js:591:3)
at ServerResponse.render (D:\Ionic\PocketBuddies\node_modules\express\lib\response.js:961:7)
at D:\Ionic\PocketBuddies\app.js:78:7
at Layer.handle_error (D:\Ionic\PocketBuddies\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (D:\Ionic\PocketBuddies\node_modules\express\lib\router\index.js:310:13)
at D:\Ionic\PocketBuddies\node_modules\express\lib\router\index.js:280:7
at Function.process_params (D:\Ionic\PocketBuddies\node_modules\express\lib\router\index.js:330:12)
at IncomingMessage.next (D:\Ionic\PocketBuddies\node_modules\express\lib\router\index.js:271:10)
I searched for the issue and it says i cannot update the response after res.end(), but I dont see any res.end() being called here when i res.json is called.
Please help me find an issue here.
I am working on a project and this error is getting me crazy.
Thanks in advance

As correctly pointed out by robertklep the problem here was that the error was not returned and hence in the group.save() function after the error it rendered the error page as well as it hit the res.json() which caused the error.
It works fine if there are no errors.
The code needs to be updated as follows to return the error if it occurs and not move on to the res.json() part.
group.save(function (err, groups) {
if(err) return next(err);
console.log('Added entries');
res.json(groups);
})
This did the trick for me by giving me the actual error which then had to be corrected post which things worked properly.

Related

pg-pool throwing error after successful queries

I am trying to send post request to update state of a record in database. I'm using pg-pool to talk to database. My code is failing in the second query where I get 'This socket has been ended by other party'. Even though I get run state update response I still get the error.
router.post('/cancel', function(reg, res, next {
db.getclient('tasksys', function(err, client, done){
if(err){
done();
return next(err);
}
var statement = "select * from runs";
let runId;
client.query (statement, function(err, result){
done () ;
if(err)
return next(err);
} else{
runId = result.rows [0][' id']
var statement= "update runs set state 'pending' where id=$1";
var args = [runId];
client.query(statement, args, function(err, result){
done()
if(err){
return next(err);
}else{
return res.send('Run state updated')
}
});
}
});
});
});
Error:This socker has been ended by other party
at Scoket.writeafterFIN [as write]
at Connection.end(...connection.js)
at Client end(...lib/client.js)
atPool.remove (...pg-pool/index.js)
at Timeout(...pg-pool/index.js)
at listenOnTimeout(<node_internal/internal/timer.js)
at processTimers(internal/timers.js){code:'EPIPE', stack:'Error:This socket has been ended by the other party'}```

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client node.js MongoDB

I have this code inside my function:
var postTitle = req.body.postTitle;
var postDescription = req.body.postDescription;
var socialLink = req.body.socialLink;
if (postTitle != undefined || postDescription != undefined || socialLink != undefined) {
next()
} else {
return err
}
client.connect().then (() => {
const database = client.db("myFirstDatabase");
const socialPosts = database.collection("socialPosts");
MongoClient.connect(uri, function(err, db) {
if (err) throw err;
const doc = { title: postTitle, description: postDescription, socialLink: socialLink };
socialPosts.insertOne(doc)
res.redirect("/")
db.close();
});
});
when I run this, I get this:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I am not sure why I am getting that, becuase I am not trying to render the front-end anywhere else, all the code you see is the entire function.
It's worth noting I am new to MongoDB, so it may be the fact that I am an amateur and could be missing smt so small!

TypeError: res.render is not a function

I am having an issue with nodejs' res.render, it's telling me its not a function. I've looked at other posts on stack overflow and they do not solve my issue.
Here's the issue....
My app has a controller, called auth.js
In it, it exports this function called updateDiscount
exports.updateDiscount = (req,res,next) =>{
const { discounts, email, filename, decide } = req.body;
switch(decide){
case "Approve":
approve(discounts,email,filename,decide, req, res);
break;
case "Deny":
deny(discounts,email,filename,decide, req, res);
break;
case "Defer":
defer(discounts,email,filename,decide, req, res);
break;
default:
return res.render('adminGrantPortal', {
message: 'You selected an option from the -- Approve/Deny/Defer -- menu which does not exist. Please contact your system administrator'
});
}
}
Next I have a WORKING METHOD called approve. So when the controller gets the approve message ( via variable decide in the switch ) It will approve a users discount in the DB. Again, this method is working...
approve = (discounts, email, filename, decide, req, res) =>{
// get discount based on name
mysqlConnection.query('SELECT id FROM discounts WHERE name=?', [discounts], async (error, results)=>{
if(error){
return res.render('adminGrantPortal',{
message: 'One or more fields either, do not exist in the database, or were filled out incorrectly during your last action.'
});
}
console.log('ayayay');
console.log(results[0]);
let discountID = results[0].id;
// Set staus in files table
mysqlConnection.query("UPDATE files SET status='approved' WHERE email=? AND filename=?", [email,filename], async (error,results)=>{
if(error){
return res.render('adminGrantPortal',{
message: 'Could not update users status, because it is not found in the database.'
});
}
// Add to discounts_users
mysqlConnection.query('INSERT INTO discounts_users (email,discountID) VALUES (?,?)',[email,discountID], async (error,results)=>{
if(error){
return res.render('adminGrantPortal', {
message: 'Cannot update the database, maybe this user already has this discount.'
});
}
return res.render('adminGrantPortal', {
message: 'Approved discount eligibility successfully.'
});
});
});
});
}
Now, I have a deny method, which means when the req.body.decide = 'deny' it goes here. This method gives me the error, specifically the line after the console.log('success');
deny = (discounts, email, filename, req, res) =>{
// Set staus in files table
mysqlConnection.query("UPDATE files SET status='denied' WHERE email=? AND filename=?", [email,filename], async (error,results)=>{
if(error){
console.log('error');
return res.render('adminGrantPortal',{
message: 'Could not update users status, because it is not found in the database.'
});
}
});
console.log('success');
return res.render('adminGrantPortal', {
message: 'Denied discount eligibility successfully.'
});
}
Why does it do this?
I've narrowed down some things that it is not.
I believe it is not that my 'results' object being returned from the mysqlconnection shares the same name as my res object, which would control the headers.
I believe it is not anything to do with my mysql, because I removed it to look like this...
deny = (discounts, email, filename, req, res) =>{
console.log('success');
return res.render('adminGrantPortal', {
message: 'Denied discount eligibility successfully.'
});
}
Yet I still get the same error....
TypeError: res.render is not a function
at deny (C:\Users\Andrew\Desktop\Project\racf\client\controllers\auth.js:187:16)
at exports.updateDiscount (C:\Users\Andrew\Desktop\Project\racf\client\controllers\auth.js:127:13)
at Layer.handle [as handle_request] (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\Andrew\Desktop\Project\racf\node_modules\express\lib\router\index.js:174:3)
Can anyone help me to figure out what I am doing wrong?
When calling the deny function, you are passing req as the 5th argument but you are trying to use it as res inside the function. Add decide to the deny function's argument list after filename.
deny = (discounts, email, filename, decide, req, res) => {
// ...
}

ReferenceError: err is not defined

I'm started working on my very first API using Mongo, Express and Node. When i tried to make API endponit for one specific user, console throw error ReferenceError: err is not defined. An error appears in the method I already used for auth part, and there it worked fine. The part of code where is the error, on line 5:
exports.userById = (req, res, next, id) => {
User.findById(id).exec(() => {
if(err || !user) {
return res.status(400).json({
err: "User not found"
});
}
req.profile = user //adds profile object in req with user info
next();
});
}
Also, the part of code where I tried to get a single user:
exports.getUser = (req, res) => {
req.profile.hashed_password = undefined;
req.profile.salt = undefined;
return res.json(req.profile);
}
I don't think the problem could be here, but there is also route line from routes file
router.get("/users/:userId", authController.requireSignin, userController.getUser);
Thanks everyone for the help!
I'm pretty sure err comes from exec:
User.findById(id).exec(err => {...});
Edit I guess you want to search by id and return something. Try this.
User.findById(id, (err, user) => {
// if error display errort
if(err) console.error(err);
// if user do not exists
if(!user) {// what is user ? the doc result ?
return res.status(400).json({
"err": "User not found" // i think use ""
});
}
req.profile = user //adds profile object in req with user info
next();
});

throw new Error('Can\'t set headers after they are sent.') causing crash

router.get('/newsfeed', (req, res, next) => {
var sql = 'select title, image, article from database';
var request = new Request(sql, function(err) {
if (err) {
console.log(err);
}
});
console.log("working");
request.on('row', function(columns) {
var t_title = columns[0].value;
var i_image = columns[1].value;
var a_article = columns[2].value;
console.log("after column");
res.render('newsfeed', { title: t_title, image: i_image, article: a_article });
console.log("after render");
});
console.log("not here");
conn.execSql(request);
console.log("after request")
});
i cant seem to find out how to stop this as it gets up to the consol.log("after render") as seen here:
working
not here
after request
after column
after render
after column
after render
and then it crashes with the throw error any help would be great
The row event fires once per row.
You can only send a response once, so you get that error when you try to send a second response for the second row.

Categories

Resources