Nodejs invalid input syntax for integer error - node.js

I using postgres sql, nodejs, express
app.get("/topic/create", function(req, res) {
var sql = "SELECT id, title FROM topic";
client.query(sql, function(err, res2) {
console.log(res2.rows);
//res.render("create", { topics: res2.rows });
});
});
this code is my router code
but when i enter that url it was error
error: invalid input syntax for integer: "create"
name: 'error',
length: 110,
severity: 'ERROR',
code: '22P02', line: '62',routine: 'pg_atoi'
i dont know reason because sql was working on other url only that app.get code doesn't working
//라우팅 작업
app.get("/", function(req, res) {
res.redirect("/topic");
});
app.get("/topic", function(req, res) {
var sql = "SELECT id, title FROM topic";
client.query(sql, function(err, res2) {
if (err) {
console.log(err);
} else {
res.render("view", { topics: res2.rows });
}
});
});
app.get("/topic/:id", function(req, res) {
var id = req.params.id;
var sql1 = "SELECT id, title FROM topic";
var sql2 = "SELECT * FROM topic where id=$1";
client.query(sql2, [id], function(err, res2) {
if (err) {
console.log(err);
} else {
client.query(sql1, function(err, res3) {
if (err) {
console.log(err);
res.status(500).send("Internal Server Error");
} else {
var list = [];
var result = res3.rows;
for (var i = 0; i < result.length; i++) {
list.push(res3.rows[i]);
}
res.render("view", { details: res2.rows, topics: list });
}
});
}
});
});
this is my router code it was same. this code is good working
i dont know why only that url make error

app.get("/topic/create", function(req, res) {
var sql = "SELECT id, title FROM topic";
client.query(sql, function(err, res2) {
console.log(res2.rows);
//res.render("create", { topics: res2.rows });
});
});
You have to put this router first then below one,
app.get("/topic/:id", function(req, res) {
var id = req.params.id;
var sql1 = "SELECT id, title FROM topic";
var sql2 = "SELECT * FROM topic where id=$1";
client.query(sql2, [id], function(err, res2) {
if (err) {
console.log(err);
} else {
client.query(sql1, function(err, res3) {
if (err) {
console.log(err);
res.status(500).send("Internal Server Error");
} else {
var list = [];
var result = res3.rows;
for (var i = 0; i < result.length; i++) {
list.push(res3.rows[i]);
}
res.render("view", { details: res2.rows, topics: list });
}
});
}
});
});
this will work, Because express take and match with first one. It get failed, That's why you got this error.

as #tadman mentioned, you need to define app.get("/topic/create function before the app.get("/topic/:id" function. otherwise, express thinks that you are executing app.get("/topic/:id" and the id is create.
Hope this helps.

Related

How to perform forloop in node js

Acoording to the data available ui should get 2 reults but getting only one since i put res.send in the looop so it is getting ended ,can anyone help me out please.......
exports.getrequestsdetails = function(req, res) {
var params = req.params;
console.log(params)
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
}
record.find(item).toArray((err, result) => {
if (err) {
return
}
if (result) {
for (var i in result) {
var id = result[i].recieved_id;
var profile = db.collection('profile');
profile.find({
'_id': new ObjectId(id)
}).toArray((err, resp) => {
if (err) {
return
}
if (resp) {
console.log(resp);
} else {}
});
}
res.send(resp);
} //end of if loop
else {
response = {
status: 'fail',
data: []
};
}
});
}
The problem is in getting the profiles. You are using mongodb's find which is asynchronous. Therefore in your for cycle you start fetching the profiles, but then you send out the res.send well before the fetching of the profiles is finished.
The call back from profile.find(... will be executed after the res.send. Apart from this, the resp variable is inside the find callback and you are trying to res.send it outside.
To deal with this, either you use async or promises. See the below code that uses promises.
var Promise = require('bluebird')
exports.getrequestsdetails = function(req, res) {
var params = req.params;
console.log(params)
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
}
record.find(item).toArray((err, result) => {
if (err) {
return
}
if (result) {
var profiles_to_get = []
var profiles = []
for (var i in result) {
var id = result[i].recieved_id;
profiles_to_get.push(get_profile(id, profiles))
}
Promise.all(profiles_to_get)
.then(() => {
res.send(profiles);
})
} //end of if loop
else {
response = {
status: 'fail',
data: []
};
}
});
function get_profile (id, profiles) {
return new Promise(function (resolve, reject) {
var profile = db.collection('profile');
profile.find({
'_id': new ObjectId(id)
}).toArray((err, resp) => {
if (err) {
reject(err)
return
}
if (resp) {
profiles.push(resp)
resolve()
} else {
reject()
}
});
})
}
}
How this works is that it creates a list of profiles to find and stores it in the var profiles_to_get = []. The you use Promise.All(profiles_to_get) which will let you do stuff after all the profiles have been fetched.
You can send only one response back to a request.
Define a variable outside the for loop, append records to it and then send it after the for loop has ended.
exports.getrequestsdetails = function(req, res) {
var params = req.params;
console.log(params)
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
}
var resList = [];
record.find(item).toArray((err, result) => {
if (err) {
return
}
if (result) {
for (var i in result) {
var id = result[i].recieved_id;
var profile = db.collection('profile');
profile.find({
'_id': new ObjectId(id)
}).toArray((err, resp) => {
if (err) {
return
}
if (resp) {
console.log(resp);
resList[i] = resp;
}
else{
}
});
}
}//end of if loop
else {
resList = {
status: 'fail',
data: []
};
}
res.send(resList);
});
Don't use for loop in asynchronous mode. Use async module instead like below.
var async = require('async');
exports.getrequestsdetails = function (req, res) {
var params = req.params;
console.log(params)
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
}
record.find(item).toArray(function (err, result) {
if (err) {
return
}
if (result) {
var list = [];
async.each(result, function (item, cb) {
var id = item.recieved_id;
var profile = db.collection('profile');
profile.findOne({
'_id': new ObjectId(id)
}, function (err, resp) {
if (err) {
return cb();
}
if (resp) {
list.push(resp);
console.log(resp);
return cb();
}
return cb();
});
}, function (err) {
res.send(list);
});
}//end of if loop
else {
response = {
status: 'fail',
data: []
};
}
});
}
You can push all the resp in list array and send after completing loop.
Like this:
exports.getrequestsdetails = function(req, res) {
var params = req.params;
console.log(params);
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
};
record.find(item).toArray((err, result) => {
if (err) {
return err;
}
if (result) {
var list = [];
for (var i in result) {
var id = result[i].recieved_id;
var profile = db.collection('profile');
profile.find({
'_id': new ObjectId(id)
}).toArray((err, resp) => {
if (err) {
return err;
}
else{
list.push(resp);
console.log(resp);
if(i===result[result.length-1]){
res.send(list);
}
}
});
}
} //end of if loop
else {
response = {
status: 'fail',
data: []
};
}
});
};
Hope this work for you
You can add all the list in to an array and finally send the data after the loop

mongodb native driver error on query

I am writing the filter using mongodb native driver, but it's driving me this error when you run the query.
In the case of this driver, it has no exec?
What is another way to perform this query?
exports.findAll = function(req, res) {
MongoClient.connect(url, function(err, db) {
var section = req.params.section;
var collection = db.collection(section);
var filter = req.query.filter ? {nameToLower: new RegExp('^' + req.query.filter.toLowerCase())} : {};
var query = collection.find(filter);
var count = 0;
collection.count(filter, function (error, result) {
count = result;
});
if(req.query.order) {
query.sort(req.query.order);
}
if(req.query.limit) {
query.limit(req.query.limit);
if(req.query.page) {
query.skip(req.query.limit * --req.query.page);
}
}
query.exec(function (error, results) {
res.json({
count: count,
data: results
});
});
});
};
Error:
TypeError: undefined is not a function
Better to use the async library in this case as it simplifies the code. In the case where you need to run multiple tasks that depend on each other and when they all finish do something else, use the
async.series() module. The following demonstrates how you can go about this in your case:
exports.findAll = function(req, res) {
var locals = {},
section = req.params.section,
filter = !!req.query.filter ? {nameToLower: new RegExp('^' + req.query.filter.toLowerCase())} : {};
async.series([
// Connect to DB
function(callback) {
MongoClient.connect(url, function(err, db) {
if (err) return callback(err);
locals.collection = db.collection(section); //Set the collection here, so the next task can access it
callback();
});
},
// Get count
function(callback) {
locals.collection.count(filter, function (err, result){
if (err) return callback(err);
locals.count = result; //Set the count here
callback();
});
},
// Query collection
function(callback) {
var cursor = locals.collection.find(filter);
if(req.query.order) {
cursor = cursor.sort(req.query.order);
}
if(req.query.limit) {
cursor = cursor.limit(req.query.limit);
if(req.query.page) {
cursor = cursor.skip(req.query.limit * --req.query.page);
}
}
cursor.toArray(function(err, docs) {
if (err) return callback(err);
locals.docs = docs;
callback();
});
}
], function(err) { //This function gets called after the three tasks have called their "task callbacks"
if (err) return next(err);
// Here locals will be populated with 'count' and 'docs'
res.json({
count: locals.count,
data: locals.docs
});
res.render('user-profile', locals);
});
};

Unable to run a function synchronously in nodejs and express

I have used wikipedia-js for this project. This is my code for summary.js file.
var wikipedia = require("wikipedia-js");
var something = "initial";
module.exports = {
wikitext: function(topicname) {
console.log("Inside wikitex funciton :" + topicname);
var options = {
query: topicname,
format: "html",
summaryOnly: false,
lang: "en"
};
wikipedia.searchArticle(options, function(err, htmlWikiText) {
console.log("Inside seararticlefunciton :");
if (err) {
console.log("An error occurred[query=%s, error=%s]", topicname, err);
return;
}
console.log("Query successful[query=%s, html-formatted-wiki-text=%s]", topicname, htmlWikiText);
something = htmlWikiText;
});
return something;
},
};
This module I am using in /wiki/:topicname route. The corresponding code in index.js is like this.
router.get('/wiki/:topicname', function(req, res, next) {
var topicname = req.params.topicname;
console.log(topicname);
var first = summary.wikitext(topicname);
res.send("Hello "+first);
});
The problem is, everytime i visit a wiki/some-topic, the last return statement of summary.js executes before htmlWikiText is populated with content. So I always see hello initial on the browser page. Although after sometime it gets printed on terminal due to console.log statement.
So how should I resolve this issue?
I'm not going to try turning this code into synchronous. I'll just correct it to work as an asynchronous version.
You need to pass in callback to wikitext() and return the value in that callback. Here is the revised code of wikitext() and the route that calls it:
var wikipedia = require("wikipedia-js");
module.exports = {
wikitext: function(topicname, callback) {
console.log("Inside wikitex funciton :" + topicname);
var options = {
query: topicname,
format: "html",
summaryOnly: false,
lang: "en"
};
wikipedia.searchArticle(options, function(err, htmlWikiText) {
console.log("Inside seararticlefunciton :");
if (err) {
console.log("An error occurred[query=%s, error=%s]", topicname, err);
return callback(err);
}
console.log("Query successful[query=%s, html-formatted-wiki-text=%s]", topicname, htmlWikiText);
callback(null, htmlWikiText);
});
}
};
router.get('/wiki/:topicname', function(req, res, next) {
var topicname = req.params.topicname;
console.log(topicname);
summary.wikitext(topicname, function(err, result) {
if (err) {
return res.send(err);
}
if (!result) {
return res.send('No article found');
}
res.send("Hello "+result);
});
});

Why can not read property when find data in node with mongoDB?

Below is my code
var mongodb = require('mongodb');
var MongodbClient = mongodb.MongoClient;
MongodbClient.connect('mongodb://localhost/test', function(err, db) {
db.collection('contact', function(err, collection) {
collection.find({}, function(err, rows) {
for(var index in rows)
console.log(rows[index]);
});
});
var contact = db.collection('contact');
contact.insert({
name:'Fred',
tel:'123456789',
address: 'Mars',
}, function(err, docs) {
if(err){
console.log("failed")
return;
}
else{
console.log('Success');
}
});
contact.find({}, function(err, docs) {
if(err) {
console.log("Can not find any!");
return;
}
for(var index in docs) {
console.log(docs.length);
var doc = docs[index];
console.log(doc.name);
}
});
});
I can find the data using mongodb shell but in node, it shows
TypeError: Cannot read property 'name' of null
on console.log(doc.name).
and also shows "undefined" when try to console.log(docs.length);
Did I do something wrong?
You are not using correctly the mongodb node API:
You should have:
contact.find({}).toArray(function(err,results) {
if (err) {
console.debug(err);
return;
}
console.debug(JSON.stringify(results));
});
More on docs.
You can try JSON.stringify(object) and then JSON.parse(object) and then try to access the property.
let xxxxxxxx = async (req, res) => {
let resultSet = [];
let object;
let perDayData = await yyyyyyyyyyy.find({});
perDayData = JSON.stringify(perDayData);
perDayData = JSON.parse(perDayData);
console.log(perDayData[0].field);
}

Event-driven asynchronous callbacks in Node js

Is there a way to block the asynchronous callback property of node.js?
Please Advice...
For example,
var express = require('express');
var app = express();
var MongoClient = require('mongodb').MongoClient,
format = require('util').format;
var cors = require('cors');
app.get('/gantt', cors(), function (request, response) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function (err, db) {
if (err) throw err;
var collection = db.collection('ganttdata');
collection.find({}, {
"_id": 0
}).toArray(function (err, results) {
var jsonString = JSON.stringify(results);
response.setHeader('Content-Type', 'text/plain');
response.send('{\"data\":' + jsonString + '}');
});
});
});
app.listen(3000);
console.log('Listening on port 3000...');
Inspite the Node.js prints the console statement first,i want app.get() to be executed.
My scenario is same as that of the above one.
This is my scenario
var ganttresult = new Array();
app.get('/get', cors(), function (request, response) {
console.log('hello');
connection.query("SELECT distinct id FROM ganttdata", function (err, rows) {
if (err) {
console.log('error in fetching ' + err);
} else {
var all_id = rows;
for (var j = 0; j < all_id.length; j++) {
console.log('hello1');
connection.query("SELECT id,tailName FROM ganttdata where id= '" + all_id[j].id + "'", function (err, rows) {
if (err) {
console.log('error in fetching ' + err);
} else {
var jsonString1 = rows;
var set_id = jsonString1[0].id;
connection.query("SELECT item_id,name,start,end FROM ganttdata where id= '" + set_id + "'", function (err, rows) {
if (err) {
console.log('error in fetching ' + err);
} else {
var jsonString2 = rows;
var gantt1 = new Object();
gantt1.id = jsonString1[0].id;
gantt1.tailName = jsonString1[0].tailName;
var series = new Array();
for (var i = 0; i < jsonString2.length; i++) {
var gantt2 = new Object();
gantt2.item = jsonString2[i];
series.push(gantt2);
gantt1.series = series;
}
//console.log(gantt1);
console.log('hi');
ganttresult.push(gantt1);
console.log(ganttresult);
}
});
}
});
}
var result = JSON.stringify(ganttresult);
console.log(result);
response.send('{\"data\":' + result + '}');
response.end();
}
});
});
When I run this code,
I get an empty resultset and when I re-run I get the result.
I guess it is due to asynchronous callback nature of node js.
Please advice...
Thanks
I have tried async.waterfall method as given below
app.get('/get',cors(), function(request,response) {
async.waterfall([
function(result) {
connection.query("SELECT id FROM Gantt",function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var all_id=rows;
for(var j=0;j<all_id.length;j++){
connection.query("SELECT id,tailName FROM Gantt where id= '"+all_id[j].id+"'",function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var jsonString1=rows;
var set_id=jsonString1[0].id;
connection.query("SELECT item_id,name,start,end FROM GanttFlight where id= '"+set_id+"'",function(err, rows) {
if (err) {
console.log('error in fetching ' + err);
}
else{
var jsonString2=rows;
var gantt1=new Object();
gantt1.id=jsonString1[0].id;
gantt1.name=jsonString1[0].tailName;
var series = new Array();
series=[];
for(var i=0;i<jsonString2.length;i++){
var gantt2=new Object();
gantt2.item=jsonString2[i];
series.push(gantt2);
gantt1.series=series;
}
ganttresult.push(gantt1);
}
});
}
});
}
var result= JSON.stringify(ganttresult);
console.log(ganttresult);
response.send(ganttresult);
ganttresult=[];
//response.send('{\"data\":'+result+'}');
response.end();
}
});
}
], function(err, status) {
console.log(status);
});
});
app.listen(3000);
console.log('Listening on port 3000...');
i am getting empty result first and when refresh the browser,i get the required result
Please Advice

Resources