I have a project written in NodeJs with mysql, async.waterfall
I have also implemented the async.waterfall to avoid my recent problem about 'callback is not a function'
but the problem still exist.
here is my async.waterfall
async.waterfall([
function (callback) {
hold.getEntry(function(data){
var ref = data.ref;
id = data.id;
var message = data.mess;
json = JSON.parse(message);
return callback(null, {'ref':ref, 'id':id, 'json':json});
});
},
function (dataa, callback) {
if(dataa.ref === null){
callback(null);
}else{
hold.checkPositionCandidate(dataa.ref, dataa.id, dataa.json, function(dataaa){
return callback(null, dataaa);
});
}
},
function(anoData, callback) {
console.log(anoData);
if(anoData === true){
//the err is here
hold.getVoterCount(id, json, function(votercount){
if(votercount == 0){
} else {
console.log('last function');
}
});
} else {
}
}
], function (err, results) {
// When finished execute this
});
and this is my getVotercount function
function getVoterCount (id, callback){
pool.getConnection(function(err, con){
con.query("select total_voters as tv from pollwatcher_view where party_id = ?", [id], function(err, rows){
setTimeout(function(){
//this callback is not a function
callback(null, {'count':rows[0].tv});
console.log(rows);
}, 2000);
});
});
}
I am very close to finish my project but that err makes me frustrate. Please someone help me.
You seem to be calling
hold.getVoterCount(id, json, function(votercount){
if(votercount == 0){
} else {
console.log('last function');
}
});
but your getVoterCount function is defined with only 2 expected parameters. I'd suggest trying to only pass in 2 parameters:
hold.getVoterCount(id, function(votercount){
if(votercount == 0){
} else {
console.log('last function');
}
});
Related
I am new to JavaScript.I am not understanding how to wait for a result of an Meteor.call method.
This is my code
//client/main.js
//Added the callback
Template.hello.events({
'click button'(event, instance) {
// increment the counter when button is clicked
instance.counter.set(instance.counter.get() + 1);
var res = Meteor.call("callMeLater","sanj",function (err,res) {
if (err) {
console.log(err);
} else {
console.log("this is the result main ", res);
}
});
console.log("this is the result ", res);
}
//server/main.js
Meteor.methods({
callMeLater :function (name) {
var callMeLaterSync =Meteor.wrapAsync(callMeLaterAsync);
var result = callMeLaterSync(name);
console.log("this is the test", result);
return result;
}
});
var callMeLaterAsync = function (name,cb) {
setTimeout(function () {
cb && cb (null ,"hey there, "+name);
},2000);
};
On the console, i get
this is the result undefined
this is the result main hey there, sanj
How do i wait for the result of Meteor.call by blocking the execution at the client.
Please help
Thanks
Just put your code into a callback method.
Meteor.call('callMeLater',"sanj", function(err, res){
if (err) {
console.log(err);
} else {
console.log("this is the result ", res);
}
});
I'm using mssql(Microsoft SQL Server client for Node.js) package from npm.I'm trying to execute a stored procedure residing in my sql server database.Everything works fine.However what I want to do is return the recordsets so that i can export this to be used in other module.Below is what I'm trying to do.
function monthlyIceCreamSalesReport (scope){
var connObj = connConfig();
connObj.conn.connect(function(err){
if(err){
console.log(err);
return;
}
connObj.req.input('Month',4);
connObj.req.input('Year',2016);
connObj.req.execute('<myStoredProcedure>', function(err, recordsets, returnValue){
if(err){
console.log(err);
}
else {
console.log(recordsets[0]); // successfully receiving the value
}
connObj.conn.close();
});
});
console.log('check for recordsets', recordsets[0]); // undefined
return recordsets[0];
}
var sqlServerObj = {
monICSalesReport : monthlyIceCreamSalesReport,
};
module.exports = sqlServerObj;
As shown in the code snippet, since the value of recordsets[0] is undefined, exporting this function is of no use.
You can't return this way in async nature. You can get it by passing the callback function
Try to give a callback function like this
function monthlyIceCreamSalesReport(scope, callback) { // pass a callback to get value
var connObj = connConfig();
connObj.conn.connect(function(err) {
if (err) {
console.log(err);
return;
}
connObj.req.input('Month', 4);
connObj.req.input('Year', 2016);
connObj.req.execute('<myStoredProcedure>', function(err, recordsets, returnValue) {
if (err) {
console.log(err);
} else {
console.log(recordsets[0]);
connObj.conn.close();
return callback(null, recordsets[0]); //return as a callback here and get that value in callback from where you called this function
}
});
});
}
var sqlServerObj = {
monICSalesReport: monthlyIceCreamSalesReport,
};
module.exports = sqlServerObj;
Note: See the comment to understand the changes
recordsets[0] is undefinded, because is defined only in connObj.req.execute function scope. You may do this in this way:
function monthlyIceCreamSalesReport (scope, cb){
var connObj = connConfig();
connObj.conn.connect(function(err){
if(err){
console.log(err);
return cb(Error("Something wrong"));
}
connObj.req.input('Month',4);
connObj.req.input('Year',2016);
connObj.req.execute('<myStoredProcedure>', function(err, recordsets, returnValue){
if(err){
console.log(err);
connObj.conn.close();
return cb(Error("Something wrong"));
}
else {
console.log(recordsets[0]); // successfully receiving the value
connObj.conn.close();
return cb(recordsets[0]);
}
});
});
}
var sqlServerObj = {
monICSalesReport : monthlyIceCreamSalesReport,
};
module.exports = sqlServerObj;
So I'm trying to create a sign up route that checks to see if the user exists first and i have the database call in a separate function that needs to return true or false when it's done. The problem is i'm not very familiar with callbacks and the whole asynchronous thing everything that i have searched for does not seem to work keeps giving me.
TypeError: callback is not a function
This is my code any help or direction would be appreciated.
function pullUserFromDatabase(username, callback) {
console.log(username); //for debug
mongodb.connect(url, function(err, db) {
if(err) {
console.log("didn't get far" + err) //for debug
}
var collection = db.collection(username);
collection.findOne({username}, function(err, item) {
if(err) {
console.log("nope it broke" + err) //for debug
} else {
console.log("it worked" + JSON.stringify(item)) //for debug
callback(true);
}
});
});
}
app.post("/signup", function(req, res) {
var username = req.headers["username"],
password = req.headers["password"],
randomSalt = crypto.randomBytes(32).toString("hex"),
passwordHashOutput = crypto.createHash('sha256').update(password + randomSalt).digest("hex");
if(!username || !password) {
res.send("Username or password not provided.")
} else if(pullUserFromDatabase(username)) {
res.send("User exist.")
}
});
You need to use the callback as follows:
function pullUserFromDatabase(data, callback) {
console.log(data.username); //for debug
mongodb.connect(url, function(err, db) {
if(err) {
console.log("didn't get far" + err) //for debug
}
var collection = db.collection(data.collection);
collection.find({"username": data.username}).count(function (err, count) {
callback(err, !! count);
});
});
};
app.post("/signup", function(req, res) {
var username = req.headers["username"],
password = req.headers["password"],
randomSalt = crypto.randomBytes(32).toString("hex"),
passwordHashOutput = crypto.createHash('sha256').update(password + randomSalt).digest("hex");
if(!username || !password) {
res.send("Username or password not provided.")
}
var data = {
username: username,
collection: "collectionName"
}
if(!username || !password) {
res.send("Username or password not provided.")
}
pullUserFromDatabase(data, function(err, exists) {
if (err) {
res.send(400, "Error - " + err);
}
else if(exists) {
res.send(200, "User exists.");
}
res.send(200, "User does not exist.");
});
});
The reason that callback is undefined is because you didn't pass a 2nd argument to pullUserFromDatabase(username) Provide a 2nd argument, eg. pullUserFromDatabase(username, function(result) {/* do something here with the result variable */})
If you're not very familiar with aync & callbacks, you might find it more intuitive to use promises, but that comes with its own learning curve.
In the context of the original code, this looks like:
...
if(!username || !password) {
res.send("Username or password not provided.");
return;
}
pullUserFromDatabase(username, function(result) {
if(result) {
res.send("User exist.");
} else {
// TODO: Handle this case. If res.send() is never called, the HTTP request won't complete
}
});
...
Also, you need to ensure your callback is always invoked. Add callback(false):
console.log("nope it broke" + err); //for debug
callback(false);
Do a similar step after "didn't get far" and then return so the callback doesn't get invoked multiple times.
With the help of glortho in this thread i built this code:
for(var i=0;i<datos.length;i++){
bittrex.getticker(datos[i].Currency, function(err, data){
if (err){
console.log('ERROR:', err);
return 'ERROR:'+ err;
} else {
if (data.message!='INVALID_MARKET') {
this.LasValueBTC=data.result.Last;
} else {
this.LasValueBTC='';
}
}
}.bind(datos[i]));
}
The problem is that outside the callback function the datos array is not updated...As it is written at the moment if i console.log(this) inside the function works great and this.LastValueBTC exists in my json, but outside the function if i console.log(datos) after the loop, the LastValueBTC does not exist..and i need to do a res.send(datos) after the loop..
What you need to do is wait for all the callbacks to complete and then call res.send.
var count = datos.length;
for(var i=0;i<datos.length;i++){
bittrex.getticker(datos[i].Currency, function(err, data){
if (err){
console.log('ERROR:', err);
return 'ERROR:'+ err;
} else {
if (data.message!='INVALID_MARKET') {
this.LasValueBTC=data.result.Last;
} else {
this.LasValueBTC='';
}
count--;
if (count === 0) {
res.send(datos);
}
}
}.bind(datos[i]));
}
Or using async
async.each(datos, function(dato, next) {
bittrex.getticker(dato.Currency, function(err, data) {
if (err){
console.log('ERROR:', err);
next(err);
} else {
if (data.message!='INVALID_MARKET') {
dato.LasValueBTC = data.result.Last;
} else {
dato.LasValueBTC='';
}
next();
}
});
}, function(err) {
res.send(datos);
});
Go through this article http://www.richardrodger.com/2011/04/21/node-js-how-to-write-a-for-loop-with-callbacks/#.VTXnFa2eDGc
It gives a good conceptual overview on what happens if you put functions inside for loop
I' have this code, know that require anonymus closure function, but don't understand how it works. If I run it there is a TypeError: undefined is not a function.
Can some one explain me anonymus closure functions with the help of this code?
mysql= require('mysql');
var connection = mysql.createConnection({});
function check_auth(input, callback){
var sql = "query to mysql";
connection.query(sql, function(err, results) {
if (err) callback(err);
if (results.length > 0) {
callback(null,results.values); //this is the line with error
}else{
callback(null, false);
}
});
};
var io = require('socket.io').listen(5678);
io.configure(function () {
io.set('authorization', function(req, callback) {
check_auth(req.query.s, function(err, result) {
if (err) {
return console.log('error:(');
}
if(result === false) {
return callback('notauth', false);
} else {
return callback(null, result);;
}
});
});
});
You code looks good, but you have an error in your code: missing ); };
mysql= require('mysql');
var connection = mysql.createConnection({});
function check_auth(input, callback){
var sql = "query to mysql";
connection.query(sql, function(err, results) {
if (err) callback(err);
if (results.length > 0) {
callback(null,results.values); //this is the line with error
}else{
callback(null, false);
}
}); // missing );
}; // missing };
io.configure(function () {
io.set('authorization', function(req, callback) {
check_auth(req.query.s, function(err, result) {
if (err) {
return console.log('error:(');
}
if(result === false) {
return callback('notauth', false);
} else {
return callback(null, result);;
}
});
});
});
There seems to be scoping issue in your code. You can't really call a function from another scope without referencing that scope. if you do:
io.configure(function () {
io.set('authorization', function(req, callback) {
var check_auth = function(...) {}; // <=== local defined
// then you can call this way
check_auth(...);
}
}
Since your check_auth() is defined outside, the callback of io.set() has its own scope, it doesn't know anything about check_auth(). So you have to point to the scope that has check_auth() defined. Something like this:
var me = this; // <==== scope that has check_auth defined
io.configure(function () {
io.set('authorization', function(req, callback) {
// then you can call this way
me.check_auth(...);
}
}
Or you can do closure approach by assigning check_auth to a variable and call it inside the callback. Something like this:
var check_auth = function(...) {};
io.configure(function () {
io.set('authorization', function(req, callback) {
// then you can call this way
check_auth(...);
}
}