Cannot set headers after they are sent to clients in node.js - node.js

My code is not working . I am beginner and don't know my problem. Kindly help.I have seen one or two solution on stackoverflow but didnot get .
This is code.
app.post('/post',(request,response)=>{
var description=request.body.description;
var contact_number=request.body.contact_number;
var city=request.body.city;
var budget=request.body.budget;
var category=request.body.optradio;
var query=connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)",[null,description,category,city,contact_number,budget],function(err){
if(err)
console.log(err);
else
response.send("successful");
});
response.redirect('/data');
});
app.get('/data',function(request,response){
connection.query("SELECT * FROM jobs ORDER BY Jobs_id DESC",(err, rows,fields) => {
if(err) {
console.log(err);
}
else {
response.render('feed', {title : 'Jobs Details',
items: rows })
}
});
});
app.listen(3000);
This is the error

pp.post('/post', (request, response) => {
var description = request.body.description;
var contact_number = request.body.contact_number;
var city = request.body.city;
var budget = request.body.budget;
var category = request.body.optradio;
var query = connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)", [null, description, category, city, contact_number, budget],
function (err) {
if (err) {
console.log(err);
} else {
response.redirect('/data');
}
});
});
app.get('/data', function (request, response) {
connection.query("SELECT * FROM jobs ORDER BY Jobs_id DESC", (err, rows, fields) => {
if (err) {
console.log(err);
}
else {
response.render('feed', {
title: 'Jobs Details',
items: rows
})
}
});
});
app.listen(3000);

There can be only one response to single HTTP request. In your code, you are first trying to send response with
response.send("successful");
but this on its own doesn't break the flow of the function which means that if the condition is actually met then this will execute and the execution continues and finds another response, in this case
response.redirect('/data');
and it will try to send another response to the original http request but at this point it is already too late because one response has already been send.
To solve this issue in general, you can place return in front of any line of code that is closing the the connection (response.send, response.redirect, ...). That way, the function's execution is terminated at the first response, whichever it is.
So you could do something like
var query=connection.query("insert into jobs(Jobs_id,Description,Category,City,Contact_number,Budget) values(?,?,?,?,?,?)",[null,description,category,city,contact_number,budget],function(err){
if(err)
console.log(err);
else
return response.send("successful");
});
return response.redirect('/data');
});

Related

How to render multiple sql query and data in Nodejs

I am having problems rendering multiple data query to page.I have done a lot of research but getting an error like Failed to look up view my code is following:
app.get('/xem', function(req,res){
pool.query("SELECT * FROM phim WHERE slider = '1' ORDER BY id DESC Limit 9", function (error, result, client){
if (!!error){
console.log('Error query');
} else {
res.render('xem', {slider:result});
}
});
pool.query("SELECT * FROM phim WHERE new = '1'", function (error, result, client){
if (!!error){
console.log('Error query');
} else {
res.render('xem', {new:result});
}
});
});
When run it code i give error:
82| <!-- END HEAD -->
83| <h1> ok </h1>
>> 84| <%= new %>
85|
new is not defined
How to fix it?
There are two issues with your approach:
res.render() ends the http request, therefore it will fail when called more than once.
You are executing two asynchronous functions and you don't take care of the order of execution
Try this:
var async = require('async');
app.get('/xem', function(req,res){
var final = {};
async.series({
slider: function(cb) {
pool.query("SELECT * FROM phim WHERE slider = '1' ORDER BY id DESC Limit 9", function (error, result, client){
cb(error, result);
})
},
new: function(cb){
pool.query("SELECT * FROM phim WHERE new = '1'", function (error, result, client){
cb(error, result)
})
}
}, function(error, results) {
if (!error) {
res.render('xem', results);
}
});
});
I don't know if your pool uses promises, so just in case this code uses async approach
The code which you have written is not correct for both queries.
You will get always first query result in response
and in first query result you are sending slider as key and expecting name in response
res.render('xem', {slider:result});
change it with
res.render('xem', {new:result});
Since you are giving name key is in second query result which is not reachable in your case
Thank you everyone. I had it working, sample code:
app.get('/xem', function(req,res){
pool.query("SELECT * FROM phim WHERE slider = '1' ORDER BY id DESC Limit 9", function (error, result, client){
var result1 = result;
link('https://drive.google.com/file/d/0BxG6kVC7OXgrQ1V6bDVsVmJMZFU/view?usp=sharing', function(data){
var dataxem = data;
pool.query("SELECT * FROM user", function (error, result, client){
var user = result;
res.render('xem', {slider:result1, link:data, user:user});
});
});
});
})
app.use('/', (req,res) => {
connection.query('select * from users', function(err, rows, fields){
if(err) return;
console.log(rows[0]);
res.send(rows);
});
});

Node.js function nested in callback returning not defined error

I'm currently working on a route the returns an array which contains the results from two separate calls to the database. Individually the functions I call in the model functions work as intended. However, when I attempt to combine them by calling the second function within the callback of the first I receive an error that the second function "is not a function". Here is the code in my list route. Note util and errorhandler are files I've created to help with the return format and shouldn't be effecting this error. Any help solving this would be appreciated, Thank you!
route/list
router.route("/list/:id").get(function(req, res) {
list.getListMovie(req.params.id, function(err, list) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
var response = [];
response["movies"] = list;
console.log(response)
list.getListTV(req.params.id, function(err, list1) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
response["tv"] = JSON.parse(list1);
console.log(response)
res.json(utils.returnFormatForDB(response));
});
});
});
the function definitions within models/list
exports.getListTV = function(userid, done) {
db.get().query('SELECT `idmedia`, `rating`, `title`, `poster_path` FROM
`list` JOIN `tv` ON list.idmedia = tv.tv_id WHERE list.idusers = ?', userid,
function(err, rows) {
if (err) return done(err);
done(null, rows);
});
}
exports.getListMovie = function(userid, done) {
db.get().query('SELECT `idmedia`, `rating`, `title`, `poster_path` FROM
`list` JOIN `movies` ON list.idmedia = movies.movie_id WHERE list.idusers =
?', userid, function(err, rows) {
if (err) return done(err);
done(null, rows);
});
}
EDIT:: I'm not sure of the proper way to mark a question as answered but by fixing the list override and making response an object I was able to get my code to work. Thanks for the help!
You are overwriting the list variable. Try
list.getListMovie(req.params.id, function(err, movieList) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
var response = {};
response["movies"] = movieList;
console.log(response)
list.getListTV(req.params.id, function(err, tvList) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
response["tv"] = JSON.parse(tvList);
console.log(response)
res.json(utils.returnFormatForDB(response));
});
});
Also, I'm pretty sure you want the response variable to be an object, not an array.

nodejs: Async and find issues

I have an array, and for each row I need to do findIfExist and save into mongodb. The code is here:
router.post('/namespaceUpload', function(req, res,next) {
var data=req.body;
var totalRows=data.allRows.length;
var conceptObject ={};
var existingConcept;
for (var i=0;i<totalRows;i++){
async.series([
conceptPrepare,
conceptFind,
conceptSave,
], function (err, result) {
console.log('kraj');
res.json('Ok');
});
}
function conceptPrepare(callback){
conceptObject.name= data.allRows[i].name;
conceptObject.user= data.userId;
callback();
}
function conceptFind(callback){
namespaces.find({name: conceptObject.name}, function(err, result) {
if (err)
next(err);
else {
if (result.length==0){
console.log('0');
existingConcept='';
} else {
console.log(result.length);
existingConcept=result[0];
}
}
callback();
});
}
function conceptSave(callback){
var namespace = new namespaces();
if (existingConcept==''){
namespace.name=conceptObject.name;
namespace.description=conceptObject.description;
namespace.lastUpdate.user=conceptObject.user;
namespace.save(function(err) {
if (err)
return next(err);
callback();
})
}
}
So I Used async.series, but only last record is written in database as much times as many array members i have. Also, I get an error " Can't set headers after they are sent." Any idea?
You're getting the Can't set headers after they are sent error message because you 're not allowed to return smtg eg : res.send,res.render more than one time but in your for loop, it goes totalRows times
try to return one value at the end of the loop

Node/Express function and callback are not breaking with return

I am creating a 'refresh data' function in Node and I cannot figure out where to place the callbacks and returns. The function continues to run. Below is a list of things the function should do. Could someone help out?
Check if a user has an api id in the local MongoDB
Call REST api with POST to receive token
Store token results in a MongoDB
Terminate function
./routes/index.js
router.post('/refresh', function(req, res) {
var refresh = require('../api/refresh');
refresh(req, function() { return console.log('Done'); });
});
../api/refresh.js
var callToken = require('./calltoken');
var User = require('../models/user'); // Mongoose Schema
module.exports = function(req, callback) {
User.findOne( {'username':req.body.username}, function(err, user) {
if(err) { console.log(err) }
if (user.api_id == 0) {
callToken.postToken(req.body.username, callback);
} else { // Do something else }
});
};
./calltoken.js
var request = require('request');
var Token = require('../models/token'); // Mongoose Schema
module.exports = {
postToken: function(user, callback) {
var send = {method:'POST', url:'address', formData:{name:user} };
request(send, function(err, res, body) {
if(err) { console.log(err) }
if (res.statusCode == 201) {
var newToken = new Token();
newToken.token = JSON.parse(body).access_token['token'];
newToken.save(function(err) {
if(err) { console.log(err) }
return callback();
});
}
});
}
};
I'm not an expert in Express but everywhere in you code in lines with if(err) { console.log(err) } you should stop execution (maybe of course not - up to you app) and return 400 or 500 to client. So it can be something like
if(err) {
console.log(err);
return callback(err); // NOTICE return here
}
On successful execution you should call return callback(null, result). Notice null as a first argument - it is according nodejs convention (error always goes as first argument).

sending data from Javascript to save in mongoDB through nodejs

I am trying to parse an object from a javascript (a blog post head and body) through a node.js server and on to save it in the mongoDB.
this is the parsing code:
function saveState( event ) {
var url = '';
var postTitle = headerField.innerHTML;
var article = contentField.innerHTML;
var post = {
title: postTitle,
article: article
};
var postID = document.querySelector('.save').getAttribute('id');
if(postID != "new"){
url += "?id=" + postID
}
var request = new XMLHttpRequest();
request.open("POST", "draft" + url, true);
request.setRequestHeader("Content-Type", "application/json");
request.send(post);
}
this is sent to this node server handler:
app.post('/draft', routes.saveDraft);
exports.saveDraft = function(req, res){
var id = url.parse(req.url, true).query.id;
var post = db.getPostByID(id);
if(id){
console.log('post id' + id);
db.savePost(id, req.body.head, req.body.article);
}
else{
db.newPost(req.body.head, req.body.article);
}
res.render('editDraft.hbs', post); //send the selected post
};
and then, sent to one of these DB functions:
exports.newPost = function (postTitle, article) {
new postCatalog({title:postTitle,
_id:1,
author:'temp',
AuthorID:2,
date:'2/3/12',
inShort:article.substring(0,100),
content:article ,
published:false
}).save(function (err, login) {
if (err) {
return console.log('error');
}
else {
console.log('Article saved');
}
});
}
exports.savePost = function (id, postTitle, article) {
postCatalog.find({_id: id}).save(function (err, login) {
if (err) {
return console.log('error');
}
else {
console.log('Draft saved');
}
});
}
now, I just can't get this to work..
I am new to node and I could really use your help!
thanks
EDITED:
the parameters being sent to the DB saving functions were not written properly.
but i'm still stuck in the same place, where the data is being sent but not saved correctly. I think there's something wrong with my getPostByID function but I can't figure it out:
exports.getPostByID =function (id) {
var post = postCatalog.find({_id: id}, function(err, post){
if(err) {
return handleError(err);
}
else{
if(post > 0){
post = post[0];
}
return post;
}
});
return post;
}
I am using express (including bodyparser) and mongoose. view engine is hbs.
thanks again.
You have to write it the asynchronous way, e.g. your getPostByID:
exports.getPostByID = function (id, callback) {
postCatalog.find({_id: id}, function(err, post) {
if (err) {
callback(err);
}
else if (post && post.length > 0) {
callback(null, post[0]);
}
else {
callback(null, null); // no record found
}
});
};
And this is true for your whole code. It's totally different and the way you tried it will never work under Node.js.
BTW there is a mongo-driver method findOne which is better suited in this special case but I didn't want to change your code too much.

Resources