I'm running the following code on Node.js and
I am trying to use mysql with nodejs: trying to run the query: select numbers from TABLE. The result comes out as:
"undefined"
function getNumbers()
{
cio.query("SELECT numbers FROM rooms WHERE durum='1'", function(err, result)
{
if (err)
throw err;
else
result[0].numbers;
});
}
var kar = getNumbers();
console.log(kar);
So, what should I do ? Please help.
Functions getNumbers() and the function called inside it don't return any values, so the result will always be undefined.
Other than that you need to handle the asynchronous nature of the function:
wait until the database query is complete before returning a value.
You can do this by using a callback function.
Example below:
function getNumbers(callback) {
cio.query("SELECT numbers FROM rooms WHERE durum='1'", function (err, result) {
if (err) throw err;
callback((result.length > 0) ? result[0].numbers : "");
});
}
getNumbers(function (result) {
console.log(result);
});
I don't know if your question depends on your console.log but your function has no return value. So when you have no return then it's undefined.
function getNumbers() {
return 'test';
}
var kar = getNumbers();
console.log(kar);
Related
I've been trying to develop an app working on Electron with an Express webserver. I also use mysql npm package for database stuff. But there's something wrong with the login function and I wasn't able to find the problem. I hope you could help.
server.js
function userLogin(data){
con.query(`SELECT * FROM players WHERE player_username = '${data.login_username}'`, (err, result, fields) => {
if (err) throw err;
var compare = bcrypt.compareSync(data.login_password, result[0].player_password);
if(compare == true) {
return "1";
}
else{
return "0";
};
});
};
app.route('/login').post((req,res) => {
res
.json(userLogin(req.body))
.end();
});
Everything is defined. No errors are shown but the function can't return, I don't understand why. If I add a console.log above return, it logs the result so the query is also OK, but the function doesn't return anything, literally anything.
Since userLogin is an asynchronous function, you can't just call it like a normal function and expect it to return a value. Instead, you should work on its results from inside the callback of con.query when they are available, like so:
app.route('/login').post((req, res) => {
con.query(`SELECT * FROM players WHERE player_username = '${data.login_username}'`, (err, result, fields) => {
var compare = bcrypt.compareSync(data.login_password, result[0].player_password);
res.json(compare ? "1" : "0").end();
});
});
You have to wait for the query to complete before sending the response. One way is to convert it into Promise and another is to use a callback
function userLogin(data, onComplete){
con.query(`SELECT * FROM players WHERE player_username = '${data.login_username}'`, (err, result, fields) => {
if (err) throw err;
var compare = bcrypt.compareSync(data.login_password, result[0].player_password);
if(compare == true) {
onComplete("1"); // do callback function
}
else{
onComplete("0");
};
});
};
app.route('/login').post((req,res) => {
userLogin(req.body, (val) => {res.json(val).end(); } ) // pass the function as callback
});
Here's my code. I'm trying to send local 'result' variable from 'returnQueryToGlobal' function, but its showing as 'undefined' in console.
I tried everything, haha!
I'm running this on a simple VPS from OVH.
export function dbQuery(sql){
var dbArguments = [];
for (var i in arguments)
{
if (i == 0) continue;
var escapeVarchar = mysql_real_escape_string(arguments[i]);
console.log(escapeVarchar);
dbArguments.push(escapeVarchar);
}
var resultToReturn;
function returnQueryToGlobal(err, result)
{
if (err) throw err;
resultToReturn = result;
}
con.query(sql, dbArguments, returnQueryToGlobal)
console.log(resultToReturn);
var dbArguments = null;
}
dbQuery("SELECT name FROM accounts");
From the looks of it, you are losing the reference to resultToReturn. Try this:
con.query(sql, dbArguments, (err, result)=>{
if (err) throw err;
resultToReturn = result;
})
The reference to resultToReturn should still be available inside the function body.
Also, since this is an asynchronous operation, you are still going to get undefined when it logs. You need to handle the value inside your callback.
Since you need to return your result to another function, you need to pass another callback, with the reult as an argument, so that it becomes available in the desired context.
//calling the function
dbQuery(sql, (resultsToReturn)=>{
//do stuff with the value of the result
})
//declaring the function
function dbQuery(callback)
{
con.query(sql, dbArguments, (err, result)=>{
if (err) throw err;
callback(result);
})
}
I am new to NodeJs and I'm finding the Non Blocking and Asynchronous nature of JS extremely difficult to understand and handle,
I have a piece of code which is supposed to Iterate an array
and for every iteration, I'm supposed to make a DB update.
Can someone provide the correct implementation of Async library functions and help fix my code?
Code example -
function updateFunction(conn, requestBody, callback) {
let arr = [];
async.each(requestBody.arr, function(item, callback) {
let sqlData = []
let columns = "";
if(item.columnData != null){
sqlData.push(item.columnData);
columns += "`columnName` = ?,";
}
if(columns != ''){
columns = columns.substring(0,columns.length-1);
let sqlQuery = 'UPDATE someTable SET '+columns
+' WHERE id = "' + item.id + '"';
conn.query(sqlQuery, sqlData, function (err, result) {
if (err) {
return callback(err, false);
}
})
}
else{
return callback(null, false);
}
columns = "";
sqlData = [];
},
function(err, results) {
//Code never reaches here, don't know why
if (err) {
return callback(err, false);
}
else{
return callback(null, true);
}
});
} // END
During your database query call, on a successful query your callback is not called, therefore causing your code to never reach the final callback.
You will want to add another return statement after your if (err) { return callback(err); } to let async know your database query is finished.
And another thing, according to the docs, the async each method's final callback does not invoke with results in its callback.
A callback which is called when all iteratee functions have finished, or an error occurs. Invoked with (err).
Therefore, it is not required for you to pass a value into the callback statement within your iteratee function.
Modify your code to do this and it will work.
conn.query(sqlQuery, sqlData, function (err, result) {
if (err) {
return callback(err);
}
return callback(null);
})
Hope this helps.
conn.query(sqlQuery, sqlData, async function (err, result) {
if (err) {
return await callback(err, false);
}
})
Something like this.. so the function callback is async here and we gave await which actually waits until the return call is finished..
This has to be a scope issue that I'm not familiar with. I have a small module I've written as so:
(function () {
var getPlanInfo = function (id, conn) {
conn.query('SELECT * FROM `items` WHERE `id` = ?', [id], function (error, result) {
if (error) console.error('Query error: ' + error.stack);
console.log(result[0]); // Everything is great
return result[0];
});
};
modules.exports.getPlanInfo = function (id, conn) { return getPlanInfo(id, conn); // Typo }
})();
Here comes the problem. When I call it from anywhere (inside the module itself or another file), the return value is always undefined. I checked from within the function, the query returns the result as expected.
var backend = require('./module.js');
var t = backend.getPlanInfo();
t is undefined. This is the same if I call that method from inside the module itself (another function within that module).
I'm familiar with the callback principle in javascript and how objects and functions have to be passed around as an argument to remain in scope. Is this the issue here or is this a node.js particularity?
I tried in in the Developer Console (Chrome), works as expected.
conn.query() looks like it is async. Thus, you can't return its result from getPlanInfo() because getPlanInfo() returns long before the result is available. Returning result[0] from the conn.query() callback just returns a piece of data back into the conn.query() infrastructure. getPlanInfo() has long before already returned.
If you want an async result, then you will have to change getPlanInfo() to use a mechanism that supports getting async results such as a direct callback or a promise or something like that.
Here's a plain callback way:
var getPlanInfo = function (id, conn, callback) {
conn.query('SELECT * FROM `items` WHERE `id` = ?', [id], function (error, result) {
if (error) {
console.error('Query error: ' + error.stack);
callback(error);
return;
}
console.log(result[0]); // Everything is great
callback(0, result[0]);
});
};
modules.exports.getPlanInfo = getPlanInfo;
Then, the caller of that module would look like this:
var m = require('whatever');
m.getPlanInfo(id, conn, function(err, result) {
if (err) {
// error here
} else {
// process result here
}
});
You don't return anything from getPlanInfo. Probably you wanted to write modules.exports.getPlanInfo = function (id, conn) { return getPlanInfo; }
(with return getPlanInfo; instead of return getPlanInfo();)
I got a file newuser.js (node.js environment featuring a mongodb database managed via mongoose) containing the following code:
//newuser.js
//basically creates new user documents in the database and takes a GET parameter and an externally generated random code (see randomcode.js)
[...]
var randomCode = require ('randomcode');
var newTempUser = new tempUser({name: req.body.name, vericode: randomCode.randomveriCode(parameter)
});
newTempUser.save(function (err){
//some output
});
//randomcode.js
//creates a random sequence of characters (=vericode), checks if code already exists in DB and restarts function if so or returns generated code
exports.randomveriCode = function randomveriCode(parameter){
[...]
var TempUser = conn.model('TempUser', TempUserSchema);
TempUser.count({vericode: generatedcode}, function(err, counter){
if (counter=='0'){
return generatedcode;
}else{
randomveriCode(parameter);
}
});
};
Problem is, that newuser.js throws an error as variable vericode is 'undefined' (thus mongoose model validations fails). The error does not occur if I skip the database query and instantly return the generated code (which in fact has got a value as verified by several console.log instructions). It occurs to me that the db query takes to long and empty or null value returned before query is complete? I thought about introducing promises unless you got any other suggestions or hints what may cause this behaviour?
Kind regards
Igor
Since querying the database is a non-blocking operation, you cannot expect the function call to return the value from the database immediately. Try passing in a callback instead:
// newuser.js
var randomCode = require('randomcode');
randomCode.randomveriCode(parameter, function(err, code) {
if (err) throw err; // TODO: handle better
var newTempUser = new tempUser({name: req.body.name, vericode: code});
newTempUser.save(function (err){
//some output
});
});
// randomcode.js
exports.randomveriCode = function randomveriCode(parameter, cb) {
var TempUser = conn.model('TempUser', TempUserSchema);
TempUser.count({vericode: generatedcode}, function(err, counter) {
if (err) return cb(err);
if (counter == '0') {
cb(null, generatedcode);
} else {
randomveriCode(parameter, cb);
}
});
};
your randomveriCode function contains calls to an asynchronous function and therefore, your function really needs to provide a callback argument like this:
exports.randomveriCode = function randomveriCode(parameter, callback){
[...]
var TempUser = conn.model('TempUser', TempUserSchema);
TempUser.count({vericode: generatedcode}, function(err, counter){
if(err) return callback(err);
if (counter=='0'){
return callback(null, generatedcode);
}else{
randomveriCode(parameter, callback);
}
});
};
You'd then call it like so:
var randomCode = require ('randomcode');
randomCode(function(err, vericode){
if(err) throw err;
var newTempUser = new tempUser({name: req.body.name, vericode: vericode});
newTempUser.save(function(err,newUser){
//do something here
});
});
Btw - you could also use a synchronous function to create a GUID. See https://www.npmjs.org/package/node-uuid.