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);
})
}
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
});
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);
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();)
How can I assign value to variable in global from double callback?
First of, I read some value from file, when its done, I pass it to some fn in callback and want to use result value in initial scope, outside callback.
I can't wrap my head around this for some reason although at first it looks trivial.
var done = function(err, value) {
if (err) {
return;
}
var resultValue = someMethod(value);
};
loadFile(done);
var resultVal = ?? //result value needed here
function loadFile(done) {
fs.realpath(filePath, function (err, resolvedPath) {
if (err) {
return done(err);
}
fs.readFile(resolvedPath, function (err, value) {
if (err) {
return done(err);
}
return done(null, data);
});
});
}
As I said in my comment you are using an asynchronous call to load a file. You want the result of someMethod stored into the global variable resultVal. Except this isn't possible.
When you call loadFile(done) a asynchronous call is made to the server. This call is being resolved by an event. If the event returns 200 the server returned the expected answer. If their is an error it will be passed to done, if not the data will be passed. Let's say this takes about 250 ms to resolve.
In the mean time JavaScript continued parsing the code, because the call was asynchronous, running in a separate thread, thus not halting the execution of the main thread. The next line that gets parsed is returnVal. However the call isn't resolved yet because this line gets executed 1 ms after the function loadFile was called. This leaves a gap of 249 ms.
The solution is to rethink your code to cope with the asynchronous call.
var done = function(err, value) {
if (err) {
return;
}
var resultValue = callBack(value);
};
loadFile(done);
function someMethod(value)
{
//execute whatever you want to do here!
}
function loadFile(done) {
fs.realpath(filePath, function (err, resolvedPath) {
if (err) {
return done(err);
}
fs.readFile(resolvedPath, function (err, value) {
if (err) {
return done(err);
}
return done(null, data);
});
});
}
Of course you can provide the function done with the callback you want. Just look at this code:
var done = function(err, value, callBack) {
if (err) {
return;
}
var resultValue = someMethod(value);
};
loadFile(done, method1);
function method1(value)
{
//execute whatever you want to do here!
}
function loadFile(done, callBack) {
fs.realpath(filePath, function (err, resolvedPath) {
if (err) {
return done(err);
}
fs.readFile(resolvedPath, function (err, value) {
if (err) {
return done(err);
}
return done(null, data, callBack);
});
});
}
Instead of declaring resultValue as : var resultValue = someMethod(value);
You can do global.resultValue = someMethod(value);
This will make resultValue as a global variable.
You can access it anywhere using global.resultValue.
Similarly,instead of using global you can also use process.
global and process are global objects for nodejs just like window is for javascript.
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.