I want to call a function that executes a query using npm-mysql .query function. The problem is that .query is asynchronous so I get a returned value = undefined and after that the mysql.query finishes the execution.
I 've tried to use promises but I couldn't synchronize the return value with the mysql.query result.
I don't want to use sync-mysql.
I want it to be in a wrapper function as shown.
function mysql_select(query)
{
var json_result
mysql_connnection.query(query, function (err, result)
{
if (err) throw err
json_result = JSON.stringify(result)
})
return json_result
}
For example i want to call this function like this:
console.log(mysql_select("SELECT * FROM table"))
and dont get the undefined result
I have checked the query , it returns the data correctly but after the function returns the json_result.
You might want to have a look into Promises:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
function mysql_select(query)
{
return new Promise(function(resolve, reject) {
mysql_connnection.query(query, function (err, result)
{
if (err) {
reject(err);
return;
}
resolve(JSON.stringify(result));
})
})
}
;(async function() {
console.log(await mysql_select('SELECT * FROM table'));
})();
Related
I´m trying to do an asynchronous query in NodeJS but keep getting undefined as a result, my code is:
async function Nuevo_Parametro() {
sqlStr = "select * from Parametros limit 10";
conCasos.query(sqlStr, function(err, Resultado, fields) {
if (err) throw err;
return Resultado;
});
}
Nuevo_Parametro().then(Resultado => {
console.log(Resultado);
});
What am I doing wrong?
Thanks in advance
you're mixing callback styles with Promises. The mysql function does not return a Promise, so you can't concatenate it. It uses a callback style - meaning the "async" part is executed in that callback you provide as a parameter.
What you need to do is wrap it up with a Promise and return that. Something along the lines of the following
function Nuevo_Parametro() {
sqlStr="select * from Parametros limit 10"
return new Promise((resolve, reject) => {
conCasos.query(sqlStr, function(err, Resultado,fields) {
if (err) {
return reject(err)
};
resolve(Resultado);
})
})
}
Nuevo_Parametro().then(Resultado => {
console.log(Resultado)
})
Here we return a promise we're creating, and in the callback query offers, I'm resolving it. I kept the variables and property names as they are for simplicity.
If you're going to use extensively the queries, perhaps it might be tedious to be newing promises everytime, so as it's mentioned in this github ticket you can use a wrapper like this one
or maybe use the native promisify utility as this comment states
const fn = util.promisify(connection.query).bind(connection);
const rows = await fn('SELECT col1, col2 FROM users WHERE email = ?', [email]);
I'm trying to use a SQL query with NodeJs but the async part really mess me up. When i print the return it gets "undefined". How can i sync this?
function SQL_test(blos) {
DB.query("Select profesor_id from materiador where materia_id = '"+blos+"';",function (err, results, fields) {
return results;
});
}
console.log(SQL_test(1));
Thanks!
So your answer is currently a promise. You'll have to read about Async and Await to do more synchronous JS.
Most of the JS for NodeJS is currently async. Below is a rewritten version of your example properly utilizing the callback method for your DB.
function callback (err, results, fields) {
if (err) {
console.log(err);
return err;
}
console.log(results, fields);
return results;
};
function SQL_test(blos) {
DB
.query("Select profesor_id from materiador where materia_id = '"+blos+"';", callback);
}
SQL_test(1);
To do the same thing synchronously you have to still have an outer level promise, otherwise Async and Await won't work how you want it to. There's no true synchronous way to handle this is javascript because it executes without waiting for the response.
function sqlTest(blos) {
return new Promise((resolve, reject) => {
DB.query(
`Select profesor_id from materiador where materia_id = '${blos}';`,
(err, results) => {
if (err) return reject(err)
resolve(results)
}
);
}
)
sqlTest(1)
.then(console.log)
.catch(console.error)
I have three operations to do one after another
1.Fetch some rows from db
2.Another mysql query in forloop for getting some data and store in variable
3.Display the data
For that i am using async waterfall method.
async.waterfall([
function(callback){
//first sql and pass the result to second function
collection.getAllCollections(function (status,error,result) {
callback(null,result);
});
},
//running another query in loop with result with previous
function(result, callback){
for(var i=0;i<result.length;i++){
collection.getImages(result[i].id,function (status,error,user) {
//append the query result to old result
result[i]['users'] = user;
});
}
callback(null,result);
}
], function (err, result) {
console.log("result",result);
});
But the problem final result does not contains the user results because the second query(query in for loop is asynchronous)
You realised the problem at hand. Your callback basically has to wait for the for loop to end.
For example like this:
async.waterfall([
function(next){
//first sql and pass the result to second function
collection.getAllCollections(function (status,error,result) {
next(null, result);
});
},
function(result, next){
var calls = [];
//putting every call in an array
result.forEach(function(resultObject){
calls.push(function(callback) {
collection.getImages(resultObject.id, function (status, error, user) {
resultObject['users'] = user;
callback(null, resultObject);
});
}
)});
//performing calls async parallel to each other
async.parallel(calls, function(err, results) {
//executed as soon as all calls are finished
if (err) {
next(err, null);
} else {
next(null, results);
}
});
}
], function (err, result) {
console.log("result",result);
});
Documentation: http://caolan.github.io/async/docs.html#parallel
why I cannot get results?
var sql_data = connection.query(sql, function(error, results, fields) {
if(error) {
console.log(error);
return;
}
var rows = JSON.parse(JSON.stringify(results[0]));
console.log(rows);
});
console.log(rows);
fiirst console.log is ok, display object,
but second says:
ReferenceError: rows is not defined
what is wrong?..
You shouldn't assign asynchronous function to a variable just like you do in first line of your code. You just call it and perform operations on the result with use of callback methods (which in this case is function(error, results, fields). Your code should look like below
connection.query(sql, function(error, results, fields) {
if(error) {
console.log(error);
return;
}
var rows = JSON.parse(JSON.stringify(results[0]));
// here you can access rows
console.log(rows);
});
// here it will be undefined
console.log(rows);
The rows variable in second console.log will be undefined because it was defined in different scope. Even if you would do var rows above the connection.query, it would still be undefined, because you assign it's value inside asynchronous function's callback. You need to read more about this kind of operations.
You should use then Promise if you want to get the query result. I prefere it to be onest. The Promise runs the command async.
function getDomain() {
return result = await dbQuery('SELECT name FROM virtual_domains ORDER BY id;');
}
// * Important promise function
function dbQuery(databaseQuery) {
return new Promise(data => {
db.query(databaseQuery, function (error, result) { // change db->connection for your code
if (error) {
console.log(error);
throw error;
}
try {
console.log(result);
data(result);
} catch (error) {
data({});
throw error;
}
});
});
}
I got this code on my NodeJS server:
function GetXML() {
fs.readFile('../slideshow.xml.old', function(err, data) {
parser.parseString(data, function (err, result) {
var json = JSON.stringify(result);
console.log(json);
return json;
});
});
}
The console.log() is working well but this is not:
.get('/', function(req, res) {
res.end(GetXML());
};
It returns undefined which is quite logic because functions are nested (I think ?). But I don't know how to make GetXML() returning a value.
It's returning undefined because you're trying to execute synchronously an asynchronous task. You have to pass a callback to your GetXML() function, like:
function GetXML(cb) {
fs.readFile('../slideshow.xml.old', function(err, data) {
parser.parseString(data, function (err, result) {
var json = JSON.stringify(result);
cb(json);
});
});
}
, and call it properly in your .get function:
.get('/', function(req, res) {
GetXML(function (json) {
res.end(json);
});
};
You should take a look at this article that explains how callbacks work in node.js.
"GetXML" is not returning a value. It can be change to:
function GetXML() {
return fs.readFile('../slideshow.xml.old', function(err, data) {
parser.parseString(data, function (err, result) {
var json = JSON.stringify(result);
console.log(json);
return json;
});
});
}