Undefined SELECT query nodejs + jade - node.js

SELECT always displays me undefined in the input text
Route:
exports.edit = function(req, res){
var id =(req.params.id);
customer = db.getCustomerById(id,function(results){
res.render('customer/edit', {customer: results });
});
};
DB function:
exports.getCustomerById = function(id,callback){
var objBD = BD();
objBD.query('SELECT * FROM user WHERE id=? ', id, callback);
};
Edit.jade :
form(id='form', method='POST', action='/customer/edit/#{customer.id}')
input(type='text', id='name', name='name' value='#{customer.name}')
input(type='email', id='email', name='email' value='#{customer.email}')
input(type='tel', id='phone', name='telephone' value='#{customer.phone}')

The callback you pass in db.getCustomerById should have the format callback(err, results). And I guess that results argument will be an array and so to pick the customer you will need to do customer = results[0].
Try the following code:
exports.edit = function(req, res){
var id =(req.params.id);
customer = db.getCustomerById(id,function(err, results){
if (err) {
console.log("Ops! Error trying to get customer ....");
throw err;
}
res.render('customer/edit', {customer: results[0] });
});
};

Related

How to get a string from query result in Nodejs

My code is in Nodejs backend below
app.get('/room_selected', function (req, res){
var clientID = 'a#gmail.com';
var room = 'Room 1';
var query = connection.query ('SELECT clientID FROM clientDevices WHERE deviceName = ?', [room],
function (err, rows, fields){
if (err) throw err;
return rows[0].clientID;
});
console.log (query);
if (clientID == query){
res.status(400).json ('success');
} else {
res.status(400).json('The selected room does not have a device attached');
}
});
When I print console.log(query), it returns [ { clientID: 'a#gmail.com' } ].
I want to return only a#gmail.com. Could you guys know how to figure out it? since I want it to compare with clientID to print out the success message, however, it printed out The selected room does not have a device attached
Please help. Thank you
In your code, you didn't wait for the query to be executed. Following is the code which will give a response only after the query is executed.
And also success should not have a status code of 400 so I have removed that which will give a status code of 200
app.get('/room_selected', function (req, res){
var clientID = 'a#gmail.com';
var room = 'Room 1';
var query = connection.query ('SELECT clientID FROM clientDevices WHERE deviceName = ?', [room],
function (err, rows, fields){
if (err) throw err;
if (rows.length && clientID == rows[0].clientID){
res.json('success');
} else {
res.status(400).json('The selected room does not have a device attached');
}
});
});

ExpressJS: How to send data to URL

I have a post request which redirects to a new route as you can see
//POST login
app.post('/login', urlencodedParser, function(req,res){
userLogin(req.body, function(response){
if(response == true){
//Activate player login in db
loginPlayerDB(req.body.username);
getPlayerId(req.body.username, function(id){
res.redirect(req.baseUrl + '/:id/profile');
});
} else{
res.send(500, "Username or Password is incorrect");
}
})
});
This function gets called
function getPlayerId(username, callback){
let sql = "SELECT PlayerId FROM users WHERE Username = (?)";
var values = [username];
db.query(sql, values, function(err, result, fields){
if(err){
console.log(err);
} else{
return callback(result);
}
})
}
It redirects to this route
app.get('/:id/profile', function(req,res){
res.render('profile/profile');
})
Everything works great except the URL on the new page is
http://localhost:3000/:id/profile
When it should be something like
http://localhost:3000/6/profile
If the player has an id of 6. How do I fix this
//Solution.
Thank you to MadWard for the help. My mistake was that in my getPlayerId function, I return result, which is an array, instead of result[0].PlayerId in order to get the specific id I was looking for
You are literally redirecting to /:id/profile. This is a string, it is fixed, and will always be '/:id/profile'.
What you want to do instead is, using template strings:
getPlayerId(req.body.username, function(id){
res.redirect(`${req.baseUrl}/${id}/profile`);
});
Using normal string concatenating like you were doing:
getPlayerId(req.body.username, function(id){
res.redirect(req.baseUrl + '/' + id + '/profile');
});

Pass URL parameter into Database query in nodejs

I am trying to pass URL parameter into the SQL query. I have a column called "puppy_id" and one of the values is puppy1.
I want to call this URL :- localhost:3000/api/puppies/puppy1
and it should execute the query in the database SELECT * FROM puppytable WHERE puppy_id='puppy1' and return the output.
I have no problem to connect to the database. But, it is showing that no data returned. I think, I am doing something wrong in executing the query.
My Code :-
index.js
var express = require('express');
var router = express.Router();
var db = require('../queries');
router.get('/api/puppies/:puppy_id', db.getPuppyStatus);
module.exports = router;
queries.js
module.exports = {
getPuppyStatus: getPuppyStatus
};
function getPuppyStatus(req, res, next) {
var puppyID = parseInt(req.params.puppy_id);
db.any('select * from puppytable where puppy_id =$1', puppyID)
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved puppies'
});
})
.catch(function (err) {
return next(err);
});
}
queries.js is in root of project directory.
It is calling from here in index.js
var db = require('../queries');
This is my output :-
{"status":"success","data":[],"message":"Retrieved puppies"}
To debug when I am doing console.log(puppyID); , it is giving me NaN
What should be the recommended way to do this ?
I don't see where req.params.family_id is coming from, but it looks like it should be req.params.puppy_id - as below - otherwise it would be undefined, which would not match anything in your database.
function getPuppyStatus(req, res, next) {
var puppyID = req.params.puppy_id;
//call puppy_id, not family_id
//puppy_id is also a string being passed in, it can't be turned into an integer
db.any('select * from puppytable where puppy_id =$1', puppyID)
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved puppies'
});
})
.catch(function (err) {
return next(err);
});
}
You're converting to a number a string "puppy1". This is the reason you're getting NaN.
I don't know what's the type of the id in your column.
You've two options:
id as number, try to send a number instead of a string and you're code should be fine.
id as string, remove the parseInt.
var puppyID = req.params.puppy_id;

mongoose findOne() query called last in function

New to Node and Mongoose here. I am having trouble running my mongoose findOne() query in a synchronous fashion within a function. Here is my code:
exports.read = function(req, res){
console.log("in articles controller read()");
//try to get article creatorId and use user providerData
//name to make fullName
var userName = "";
//get article creator id
User.findOne({ '_id': req.article.creator._id }, function(err, person){
if(err) { return next(err)};
if (!person) { return next(new Error('Failed to find user'))};
console.log("found person");
//return providerData name
userName = person.providerData.name;
});
//assign username value to article creator
var splitName = userName.split(' ');
req.article.creator.fullName = userName;
req.article.creator.firstName = splitName[0] || '';
req.article.creator.lastName = splitName[1] || '';
console.log("end of read()";
res.json(req.article);
};
When I look at my console, I expect to see the logs in the following order:
in articles controller read()
found person
end of read()
But instead, I see in my console:
in articles controller read()
end of read()
found person
I'm assuming that this issue has to probably do with the async nature of node?
Basically, I would like to run the findOne() query before assigning values to my req object so that I can actually have something to assign. Please help.
Callbacks are async, you need to move your code inside it.
User.findOne({ '_id': req.article.creator._id }, function(err, person){
if(err) { return next(err)};
if (!person) { return next(new Error('Failed to find user'))};
console.log("found person");
//return providerData name
userName = person.providerData.name;
//assign username value to article creator
var splitName = userName.split(' ');
req.article.creator.fullName = userName;
req.article.creator.firstName = splitName[0] || '';
req.article.creator.lastName = splitName[1] || '';
res.json(req.article);
});
You are using the Nodejs which is asynchronous and event-driven.
So it will call the method in sequence way:
console.log("in articles controller read()");
User.findOne();
console.log("end of read()";
but User.findOne is the database call which is slow, so it call User.findOne and it will go tho then another method call and when they will return the result it will print.
That's by you will get the result as
in articles controller read()
end of read()
found person
For solving this you can use the async.js or you can directly put the value inside the findOne result:
exports.read = function(req, res){
console.log("in articles controller read()");
//try to get article creatorId and use user providerData
//name to make fullName
var userName = "";
//get article creator id
User.findOne({ '_id': req.article.creator._id }, function(err, person){
if(err) { return next(err)};
if (!person) { return next(new Error('Failed to find user'))};
console.log("found person");
//return providerData name
userName = person.providerData.name;
//assign username value to article creator
var splitName = userName.split(' ');
req.article.creator.fullName = userName;
req.article.creator.firstName = splitName[0] || '';
req.article.creator.lastName = splitName[1] || '';
console.log("end of read()");
res.json(req.article);
});
}

Issue with MySQL + Node.js + Jade on select data

Error
Problem: Cannot read property 'length' of undefined at
jade_debug.unshift.lineno (eval at
(C:\Users\Dev\Node_js\node_modules\jade\lib\jade.js:160:8),
:111:31) at eval (eval at
(C:\Users\Dev\Node_js\node_modules\jade\lib\jade.js:160:8),
DB function
exports.selectRows = function(){
var objBD = BD();
objBD.query('SELECT * FROM usr ', function(results) {
return(results);
});
}
Route
exports.index = function(req, res) {
res.render('customer/index',{ customers: db.selectRows() });
};
index.jade
each item in customers
tr
td
a(href='/customer/details/#{item.id}') #{item.id}
td #{item.name}
td #{item.email}
td #{item.phone}
Problem with your code is that the selectRows method is executed asynchronously and db.selectRows() expression in your handler method always return undefined value and hence the execption (customers template variable is undefined).
You should add the following changes to your code in order to have it working correctly:
DB function :
exports.selectRows = function(callback){
var objBD = BD();
objBD.query('SELECT * FROM usr ', callback);
}
Route:
exports.index = function(req, res) {
db.selectRows(function(results){
res.render('customer/index', { customers: results });
});
}
Sometimes you may have a situation (very common Node.js pattern) where your callback gets two parameters:
first would be an error - it should be undefined if DB query was successful
second would be DB query results data
In case of two parameters (error and results) your route should look as follows:
exports.index = function(req, res) {
db.selectRows(function(err, results){
if (err) return res.send(500, "DB QUERY ERROR");
res.render('customer/index', { customers: results });
});
}
You can also simplify your index.jade
each item in customers
tr
td: a(href='/customer/details/#{item.id}')= item.id
td= item.name
td= item.email
td= item.phone
I hope that will help.

Resources