I have a web app containing four routes out of which two are executing insert query in Postgresql and two are executing select query. The post in insert is working fine but post in select query is not working. Is this problem of the query or post i'm unable to understand. Printing the post var gives undefined. Please help.
ws.post('/prab',function(req,res){
var vill = req.body.addr;
console.log(vill);
if(!(vill = null) )
{
pg.connect(conString,function(err,client,done){
if(err){
return console.error('Could not connect to postgres' , err);
}
var results = [];
var query = client.query("SELECT * FROM \"Area_info\" WHERE \"FOLDER_NAME = $1",[vill],function(err,result){
console.log(vill);
console.log(query);
query.on('row', function(row) {
results.push(row);
});
query.on('end', function() {
done();
return res.json(results);
});
if(err) {
return console.error('error running query', err);
}
else{
if(results.length == 0)
{
res.render('abs');
}
else{
res.render('re');
}
}
})
})
}
});
I solved my problem. It was silly on my part as i picked bootstrap template , i forgot to change the type of button from button to input. Thanks everybody to help me and waste your precious time on my silly mistake. I would be careful from next time.
This might be your problem:
if(!(vill = null) )
You're doing an assignment to vill and not the equality operator (== or ===). The assignment operator according to the Node REPL returns whatever is on the right hand side which in this case is null. Therefore, the statement (!(vill=null))above will always evaluate to true.
Related
First off, don't worry, it's a tiny data set - I realise it wouldn't be wise to dump an entire production DB to a single screen via an API... I just need to get a JSON dump of entire (small) DB to return via an API endpoint in a Node.js application.
My application does successfully return single records with this code:
MongoClient.connect("mongodb://localhost:27017/search", function (err, db) {
if(err) throw err;
db.collection('results', function(err, collection) {
// search for match that "begins with" searchterm
collection.findOne({'string':new RegExp('^' + searchterm, 'i')}, function(err, items){
// get result
var result;
if (items == null || items.result == null){
result = "";
}
else {
result = items.result;
}
// return result
res.send(result);
});
});
});
So I know Node is talking to Mongo successfully, but how can I tweak this query/code to basically return what you get when you execute the following on the MongoDB command line:
$ db.results.find()
This is snippet.
model.find({}).exec(function (err, result) {
if (err) {console.error(err); return;}
else return result;
});
First use your predefined model and call find. the logic is to place a empty object {} essentially rendering . select all from this model.
Make sense?
Exactly as you've described it.
collection.find({}).exec((err, result) => {
if (err) {
console.log(err);
return;
}
if (result.length > 0) {
// We check that the length is > 0 because using .find() will always
// return an array, even an empty one. So just checking if it exists
// will yield a false positive
res.send(result);
// Could also just use `return result;`
});
Thanks guys, I appreciate your answers pointing me in the right direction, in terms of using {} as the query. Here is the code that eventually worked for me:
db.collection('results', function(err, collection) {
collection.find({}).toArray(function(err, docs) {
res.send(docs);
});
});
The crucial element being the toArray(...) part.
Hello I am new to Postgresql and I wanted to learn how one handles 0 results as an error is thrown. Essentially I want to get a user if it doesn't exist, return null if one doesn't, and have an error handler. Below is the current code I am using. Any tips on a better way to do this are appreciated!
var options = {
// Initialization Options
promiseLib: promise
};
var pgp = require('pg-promise')(options);
var connectionString = 'postgres://localhost:5432/myDbName';
var db = pgp(connectionString);
function getUser(id) {
let user = new Promise(function(resolve, reject) {
try {
db.one('select * from users where loginName = $1', id).then(function(data) {
console.log(data);
resolve(data);
}).catch (function (e) {
console.log('error: '+e);
reject(e);
});
}
catch (e) {
console.log('error: '+e);
reject(e);
}
});
return user;
}
output in console:
error: QueryResultError {
code: queryResultErrorCode.noData
message: "No data returned from the query."
received: 0
query: "select * from users where loginName = 'someUserName'"
}
I am the author of pg-promise.
In the realm of promises one uses .then to handle all normal situations and .catch to handle all error situations.
Translated into pg-promise, which adheres to that rule, you execute a database method that resolves with results that represent all the normal situations, so anything else ends up in .catch.
Case in point, if returning one or no rows is a normal situation for your query, you should be using method oneOrNone. It is only when returning no row is an invalid situation you would use method one.
As per the API, method oneOrNone resolves with the data row found, or with null when no row found, which you can check then:
db.oneOrNone('select * from users where loginName = $1', id)
.then(user=> {
if (user) {
// user found
} else {
// user not found
}
})
.catch(error=> {
// something went wrong;
});
If, however, you have a query for which returning no data does represent an error, the proper way of checking for returning no rows would be like this:
var QRE = pgp.errors.QueryResultError;
var qrec = pgp.errors.queryResultErrorCode;
db.one('select * from users where loginName = $1', id)
.then(user=> {
// normal situation;
})
.catch(error=> {
if (error instanceof QRE && error.code === qrec.noData) {
// found no row
} else {
// something else is wrong;
}
});
Similar considerations are made when choosing method many vs manyOrNone (method any is a shorter alias for manyOrNone).
Type QueryResultError has a very friendly console output, just like all other types in the library, to give you a good idea of how to handle the situation.
In your catch handler for the query, just test for that error. Looking at pg-promise source code, a code of noData is 0. So just do something like this:
db.one('select * from users where loginName = $1', id).then(function(data) {
console.log(data);
resolve(data);
}).catch (function (e) {
if(e.code === 0){
resolve(null);
}
console.log('error: '+e);
reject(e);
});
I am building a page which needs to retrieve and list data from several different Mongodb collections. I've been doing separate queries in the Express router function then bunging the results into an array which is passed to the page where the relevant data for each section are accessed. This has worked ok so far with up to three queries, but, if I add a fourth query I get an error.
The router function looks like this:
router.get('/thetest',function(req,res){
var finalResult = {};
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/myapp';
MongoClient.connect(url, function(err, db){
if(err){
console.log("Connection Error",err);
}else{
var collection = db.collection('cats');
collection.find({}).toArray(function(err,result){
if(err){
console.log("Error retrieving cats");
}else if (result.length){
finalResult.ctlist = result;
console.log("cats OK");
}
});
var collection = db.collection('mice');
collection.find({}).toArray(function(err,result){
if(err){
console.log("Error retrieving mice");
}else if (result.length){
finalResult.mclist = result;
console.log("mices OK");
}
});
var collection = db.collection('cheese');
collection.find({}).toArray(function(err,result){
if(err){
console.log("Error retrieving cheese");
}else if (result.length){
finalResult.chlist = result;
console.log("Cheese OK");
}else{
console.log('No Documents');
}
});
var collection = db.collection('mice');
collection.find({}).sort({tailLength:1}).limit(3).toArray(function(err,result){
if(err){
console.log("Error retrieving alert bookings");
}else if (result.length){
finalResult.mtlist = result;
console.log("Mouse tail length ok");
res.render('thetest',{
"thelist":finalResult
});
}
db.close();
});
}
});
});
(using dummy collection names)
So, there are four queries made to three different collections. The results are listed in a Jade template using an each loop.
If I comment out any one of the four queries and just run the other three it works fine: the results are listed on the page. If I uncomment and run all four queries then Node will choke and, obviously, nothing is listed on the page. None of the collections are above about half a dozen documents in size with a handful of fields in each.
I'm pretty new to all this and I understand that this may not be the best way to do what I am attempting.
Can anybody a) explain where I'm going wrong and/or b) suggest a better approach?
Thanks
I think the problem is due to your code.
Node.js is an asynchronous programming language, so all the operations works parallely.
In your code 'db.close();' close the database connection. For eg. if all the db operation works parallely and the 4th one (in your code) execute firstly then it close the database connection. So it is not a good programming style.
So you can use 'async' library for solving this.
https://github.com/caolan/async
Sample code :
async.parallel([
function(callback){
dbOperation1(query, callback);
},
function(callback){
dbOperation2(query2, callback);
},
function(callback){
dbOperation3(query3, callback);
},
function(callback){
dbOperation4(query4, callback);
}
],
function(err, results){
if (err) {
renderError(err);
} else {
renderHTML(results[0], results[1], results[2], results[4]);
}
});
If you comment all four condition then I am pretty sure that you are commenting res.render('thetest',{
"thelist":finalResult
});
Hence code is chocked. Because express API always wait for response and if you not provide response sentence, then for some time is going to wait and then crash out.
Solution : You must write your response statement out of condition.
Been stuck on this problem for hours. The below code:
router.route("/contact")
.get(function(req,res){
var response = {};
Contact.find({},function(err,data){
if(err) {
response = {"error" : "Error fetching data"};
} else {
response = {"message" : data};
}
res.json(response);
});
})
Above query produces result with all the contacts in the database but
router.route("/contact/department/:dept")
.get(function(req,res){
var response = {};
var arrDept = req.params.dept.split(",");
if(arrDept.length == 0){
response = {"error": " Please enter Department keywords"};
}
else{
response = {};
arrDept.forEach(function(currentValue){
Video.find({dept: '/'+currentValue+'/i'}, function(err, data){
if(err){
response[currentValue] = "No data found";
}else{
response[currentValue] = data;
}
});
});
}
res.json(response);
});
this code does not produce any output.
The code is entering the forEach loop in the else block but the query is not generating any result even if I modify the query to a basic one like
Video.find({},function(err, data){
if(err){
response[currentValue] = "No data found";
}else{
response[currentValue] = data;
}
});
The response JSON is still returned blank.
PS: Problem has been simplified as is only an example of actual problem i am facing in the code.
update after answer found.
res.json(response)
was written outside the query that is why a blank json was getting returned. The above scenario can be solved using promise as follows:
var promise = Contact.find({ dept: { $in: arrayDept }}).exec();
promise.then(function(resultJson) { res.json(resultJson); });
This can be used to execute all the queries in the array and return the complete json.
Your res.json(response); in the non-working example is outside the callback of your MongoDB query, that is you are writing the response before the query's callback was actually executed and therefore your result is empty.
app.js
MyDatabase = require("./mysql");
...
var availableRooms = mydb.checkRoomStatus();
console.log("Rooms " + availableRooms);
//undefined.
mysql.js
MyDatabase.prototype.checkRoomStatus = function() {
this.con.query('SELECT * FROM rooms WHERE status = "open" LIMIT 1',function(err,rows){
if(err) throw err;
console.log('Data received from Db:\n');
console.log(rows); // results are coming here.
return rows;
});
}
The first console.log is outputting "undefined" for availableRooms variable.
I think i should use a callback function for this kind of request.
But i dont know how to use it. When i search in internet, i dont find anyone using separate file for mysql to get callback results.
You need to return callback(rows) to return your rows and you need to catch it in your callback. I hope it's clear. Try this out, and see if it works.
change your mysql code to
MyDatabase.prototype.checkRoomStatus = function(callback) {
this.con.query('SELECT * FROM rooms WHERE status = "open" LIMIT 1',function(err,rows){
if(err) throw err;
console.log('Data received from Db:\n');
console.log(rows); // results are coming here.
return callback(rows);
});
Now in app.js
MyDatabase = require("./mysql");
...
mydb.checkRoomStatus(function(res){
var availableRooms = res;
console.log("Rooms " + availableRooms);
});