I am pretty new to nodejs.
What I want my code to do it to query a database a number of times, collect data from all the queries in one variable and then use it somewhere.
But I guess nodejs instead of waiting for the result of the queries, execute without blocking. This is what I think is happening. Sorry if I am wrong.
for (var i = step_min; i < (step_max); i += step) {
query = 'select count(' + colName + ') as num_count from ' +
rows[0].tablename + ' where ' + 'dictionaryid=' +
rows[0].dictionaryid + ' and ' + colName + ' between ' + i +
' and ' + (i + step);
connection.query(query, function(err, rows1, fields) {
if (err) {
console.log(err);
throw err;
}
try {
console.log("$$$$$$$$$$$$$$$ pushed : "+ rows1[0].num_count);
contents.push(rows1[0].num_count);
console.log('contents : '+ contents+'\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
}
});
console.log("##################### " + query + "\n");
console.log('contents : '+ contents+'\n');
}
Any advice either on how to block nodejs till the result from query is obtained or otherwise a way to restructure my code ?
Thanks in advance.
You are correct that it is not waiting for your queries before executing. You can look at the node-mysql-queues module which you can use to queue queries, and execute the given callback after all have executed (it will also allow you do perform transactions)
Another (hack) approach is to set a counter of the number of queries you are executing. In the callback of each transaction save the result into your return object and decrement the counter. If it is <= 0 then all your queries have completed, and you can execute your main callback with the return object.
Also, watch out for SQL injection.
try this: https://github.com/luciotato/waitfor
your code with wait.for:
for (var i = step_min; i < (step_max); i += step) {
query = 'select count(' + colName + ') as num_count from ' +
rows[0].tablename + ' where ' + 'dictionaryid=' +
rows[0].dictionaryid + ' and ' + colName + ' between ' + i +
' and ' + (i + step);
var rows1 = wait.forMethod(connection,"query",query); //waits until callback
console.log("$$$$$$$$$$$$$$$ pushed : "+ rows1[0].num_count);
contents.push(rows1[0].num_count);
}
console.log("##################### " + query + "\n");
console.log('contents : '+ contents+'\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
....
}
Doing something like below could be a work around.
//Its just a test code whatever came to mind first so I'll tune it later...
var contents = [];
var lock = 0;
for (var i = step_min; i < (step_max + step); i += step) {
lock++;
}
for (var i = step_min; i < (step_max + step); i += step) {
query = 'select count(' + colName + ') as num_count from ' + rows[0].tablename + ' where ' + 'dictionaryid=' + rows[0].dictionaryid + ' and ' + colName + ' between ' + i + ' and ' + (i + step);
connection.query(query, function(err, rows1, fields) {
if (err) {
console.log(err);
throw err;
}
try {
console.log("$$$$$$$$$$$$$$$ pushed : " + rows1[0].num_count);
contents.push(rows1[0].num_count);
console.log('contents : ' + contents + '\n');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("Syntax Error for input function");
}
}
lock--;
if (lock == 0) {
queryDone();
}
});
}
function queryDone() {
console.log("##################### " + query + "\n");
console.log('contents : ' + contents + '\n');
var id = obj.exptID + '.' + obj.exptITR + '.' + obj.nodeID + '.' + obj.resourceName + '.' + colName;
serie = {
name: colName,
data: contents,
id: id
};
console.log("--------------------\n " + step_max + "\n" + step_min + "\n------------------------\n");
}
The approach is to fire a function when all queries are done as Nick said...