How to pass parameters to mysql query callback in nodejs
I'm trying to figure out the correct way of passing custom data to a query call to be made available in the callback. I'm using MySQL library in nodejs (all latest versions).
I have a call to connection.query(sql, function(err, result) {...});
I couldn't find a way to 1) pass custom data/parameter to the call so that 2) it can be made available when the callback is invoked. So what is the proper way of doing so?
I have the following (pseudo-code):
...
for (ix in SomeJSONArray) {
sql = "SELECT (1) FROM someTable WHERE someColumn = " + SomeJSONArray[ix].id;
connection.query(sql, function (err, result) {
...
var y = SomeJSONArray[ix].id;
};
}
From the code above, I need to be able to pass the current value of "ix" used in the query to the callback itself.
How do I do that?
If you are using node-mysql, do it like the docs say:
connection.query(
'SELECT * FROM table WHERE id=? LIMIT ?, 5',[ user_id, start ],
function (err, results) {
}
);
The docs also have code for proper escaping of strings, but using the array in the query call automatically does the escaping for you.
https://github.com/felixge/node-mysql
To answer the initial question with a complete answer/example to illustrate, wrap the callback with an anonymous function which immediately creates a scope containing a "snapshot" if you will of the data passed in.
var ix=1;
connection.query('SELECT 1',
(function(ix){
return function(err, rows, fields) {
console.log("ix="+ix);
console.log(rows);
};
})(ix));
For those new to this concept as I was 20 minutes ago, the last })(ix)); is the outer var ix=1 value which is passed into (function(ix){. This could be renamed (function(abc){ if you changed the console.log("ix="+abc);
fwiw (Thanks Chris for the link which filled in the blanks to arrive at a solution)
While it is OK to pass variables or objects to a mysql query callback function using the tactic described earlier -- wrapping the callback function in an anonymous function -- I think it is largely unnecessary, and I'll explain why with an example:
// This actually works as expected!
function run_query (sql, y) {
var y1 = 1;
connection.query (sql, function (error, rows, fields) {
if (! error)
{
var r = rows[0];
console.log ("r = " + r[1]);
console.log ("x = " + x);
console.log ("y = " + y);
console.log ("y1= " + y);
console.log ("");
}
else
{
console.log ("error = " + error);
}
});
};
var x = 5;
console.log ("step 1: x = " + x);
run_query ("SELECT 1", x);
x = x + 1;
console.log ("step 2: x = " + x);
run_query ("SELECT 1", x);
x = x + 1;
console.log ("step 3: x = " + x);
Produces the following output:
step 1: x = 5
step 2: x = 6
step 3: x = 7
r = 1
x = 7
y = 5
y1= 5
r = 1
x = 7
y = 6
y1= 6
The fear is that the second call to run_query() will overwrite the variable y and/or y1 before the first call to run_query() has a chance to invoke its callback function. However, the variables in each instance of the called run_query() function are actually isolated from each other, saving the day.