"callback is not a function" Node.Js - javascript

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

Wait for Meteor.call result on Client

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);
}
});

returning data from node mssql execute functions

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;

Node.js mongodb trouble with callbacks

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.

Scope issue calling a callback function inside a loop in node.js

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

Anonymous function and closures in socket.io

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(...);
}
}

Categories

Resources