node function result undefined - javascript

this function check_auth return always undefined ? cookie is ok result is ok, maybe the problem is the async call if yes how can fix it?
I don't wont connection if the function is not satisfied
function check_auth(req,res){
var cookie=check_cookie(req);
var check_result_ret;
if(cookie){
console.log("exist cookie: "+cookie);
var sql = 'SELECT session_id,username,id FROM session WHERE session_id = ' + connection.escape(cookie);
connection.query(sql, function(err, results) {
if (err) throw err;
if (results.length > 0 && results[0]['session_id'] ==cookie) {
users[results[0]['session_id']]={username:results[0]["username"],id:results[0]["id"]};
check_result_ret=1;
}else{
check_result_ret=0;
}
});
}else{
check_result_ret=0;
}
return check_result_ret;
}
server node part
switch (path) {
case '/':
var test=check_auth(request,response);
console.log("result",test);
if(test==1){
fs.readFile("main.html", 'utf-8', function (error, data) {
//make somthing
});
}else{
send404(response);
}
break; etc....

The problem is check_auth returns check_result_ret before the callback function(err, results) of connection.query is called .
I guess you need to read more on how asynchronous programming works .This might help http://www.sebastianseilund.com/nodejs-async-in-practice
maybe this helps,
check_auth(req,res){
...do stuff
connection.query(sql, function(err, results) {
if (err) throw err;
if (results.length > 0 && results[0]['session_id'] ==cookie) {
users[results[0]['session_id']]={username:results[0]["username"],id:results[0["id"]};
check_result_ret=1;
}
else{
check_result_ret=0;
}
var test = check_result_ret;
if(test==1){
fs.readFile("main.html", 'utf-8', function (error, data) {
//make somthing afer reading the file
anotherAsyncCall(input,options,function(output){
//do something with output
});
});
}
else{
send404(response);
}
})

Related

JS - How to return mysql query values properly

I'm pretty new to JS since I've switched from C#.
My Question is how I can return mysql query values without problems.
chat.registerCmd('getid', (player, arg) => {
db.getPlayerPermission(player.socialId, function(permission){
PermissionValue = permission;
});
var vname;
var name;
if(arg.length <= 1) {
chat.send(player, '/getid [Vorname] [Name]');
return;
}
vname = arg[0];
name = arg[1];
db.getCharIdByName(vname, name, function(charid){
chat.send(player, 'Die ID des Spielers ist: ' + charid);
});
});
Is this a good way to return query values?
export function getPlayerPermission(socialid, callback){
connection.query('SELECT permission FROM permissions WHERE socialid=?',socialid, function(err, rows){
if(err){
console.log(err);
return;
}
callback(rows[0].permission);
});
}
You are using a callback-based approach which is completely fine. You can also use promises. With the callback apparoach, you can return both errors and the result of queries. The first argument can be the error while the second argument can be the returned value
export function getPlayerPermission(socialid, callback) {
connection.query('SELECT permission FROM permissions WHERE socialid=?',socialid,
function(err, rows){
if(err){
console.log(err);
callback(err);
return;
}
callback(null, rows[0].permission);
});
}
Now in your other file, you can call the function as follows
chat.registerCmd('getid', (player, arg) => {
db.getPlayerPermission(player.socialId, function(dbErr, permission) {
// since JS is asynchronous, you need to be in callback function to execute the rest of the code after you get the data from first query
if (dbErr) {
console.log(dbErr);
return;
}
// Now permission variable has data returned from the query
PermissionValue = permission;
var vname;
var name;
if(arg.length <= 1) {
chat.send(player, '/getid [Vorname] [Name]');
return;
}
vname = arg[0];
name = arg[1];
db.getCharIdByName(vname, name, function(charid){
chat.send(player, 'Die ID des Spielers ist: ' + charid);
});
});
});

Waiting for data from async nested Functions within JQuery $.each in Javascript

this is a follow up question to Asynchron Errorhandling inside $.each. As mentioned in the comments there, i want to handle data after the last async job from a $.each loop.
So for instance:
var errors = 0;
var started = 0;
var successful = 0;
$.each(..., function(){
started++;
connection.query('INSERT INTO tableName SET ?', post, function(err, result)
{
if (err) {
if (err.code === 'ER_DUP_ENTRY')
{ errors++; }
else
{ throw err; }
} else { successful++;}
if (started == successful + errors) {
// all done
console.log(errors + " errors occurred");
}
});
});
In this case everything logs out properly when the // all done comment is reached. But what if i want to use this data later on instead of just logging it out.
Is there a way to wait for this data outside of the $.each scope? Or do i always have to handle everything in the nested function?
You can use promises instead
var promises = [];
$.each(..., function() {
var promise = new Promise(function(resolve, reject) {;
connection.query('INSERT INTO tableName SET ?', post, function(err, result) {
if (err) {
resolve(err.code);
} else {
resolve(result);
}
});
});
promises.push(promise);
});
var result = Promise.all(promises);
And then when you want to use the data, you do
result.then(function(data) {
// use data array looking like ["result data", "result data", "ER_DUP_ENTRY" .. etc]
})

How to rewrite asynchronous function (node.js, monk)

I'm trying to write an asynchronous function to give me a random document from a mongodb collection.
var getRandDoc = function(){
var db = monk('localhost/data');
var coll = db.get('coll');
coll.count({}, function(err, count){
if (err) console.log(err);
else {
coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){
if (err) console.log(err);
else{
db.close();
return out[0]['name'];
}
});
}
});
}
In another file, I call this function with something like:
console.log(test.getRandDoc());
And I get undefined
What am I doing wrong and how do I fix it?
It's the usual node callback confusion. If you don't want to use promises then getRandDoc() needs to accept a callback and then call it with the results in the coll.find(...) method. So something like this:
var getRandDoc = function(cb){
var db = monk('localhost/data');
var coll = db.get('coll');
coll.count({}, function(err, count){
if (err) console.log(err);
else {
coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){
if (err) return cb(err)
else{
db.close();
return cb(null, out[0]['name']);
}
});
}
});
}
You probably want to pass back that error too, so:
test.getRandDoc(function(err, name){
});
A promise based version is going to look something like this:
var getRandDoc = function(){
var db = monk('localhost/data');
var coll = db.get('coll');
var deferred = Q.defer();
coll.count({}, function(err, count){
if (err) deferred.reject(err);
else {
coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){
if (err) deferred.reject(err);
else{
db.close();
deferred.resolve((out[0]['name']);
}
});
}
});
return deferred.promise;
}
But it's still not going to give you a straight forward variable assignment. You'll wind up calling it something like this:
test.getRandDoc().then(function(res){}).fail(function(err){});
Welcome to node!

Node async control flow

I am trying to work with twitter data in node and am running into some road blocks that I think should be related to node style coding. The block of code is meant to grab the tweets, check if the text is in mongo and if not insert it.
The first stumbling block I find is that on trying to print out i to the console it will always iterate through each i before it starts iterating through the cursor. I think if I could clear that up it may help me going forward. Is this enough info to help me out?
What I have is:
T.get('statuses/user_timeline', options , function(err, data) {
var db = MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err)
throw err;
console.log("connected to the mongoDB !");
myCollection = db.collection('test_collection2');
for (var i = 0; i < data.length ; i++) {
//let's wrap this in a loop
docu = data[i];
//console.dir(data);
console.dir(i);
var cursor = myCollection.find({text : data[i].text}).limit(1);
cursor.each(function(err, doc) {
if (doc != null) {
console.dir('doc is not null');
console.dir(doc.text);
} else {
console.dir('doc is null - inserting');
myCollection.insert(docu, function(err, records){
console.log("Record added as "+records.text);
});
}
})
}
});
})
The problem is just because Javascript is async. The loop is finished before the find function in Mongo gives you a return value.
I would do the Following, or something similar - just to explaine the concept:
T.get('statuses/user_timeline', options , function(err, data) {
var db = MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err)
throw err;
console.log("connected to the mongoDB !");
myCollection = db.collection('test_collection2');
var myfunction = function(correct_i,docu){
var cursor = myCollection.find({text : data[correct_i].text}).limit(1);
cursor.each(function(err, doc) {
if (doc != null) {
console.dir('doc is not null');
console.dir(doc.text);
} else {
console.dir('doc is null - inserting');
myCollection.insert(docu, function(err, records){
console.log("Record added as "+records.text);
});
}
})
};
for (var i = 0; i < data.length ; i++) {
//let's wrap this in a loop
docu = data[i];
//console.dir(data);
console.dir(i);
myfunction(i,docu);
}
});
})
This way each lookup/find to Mongo will have the correct i. because the function gets it as an parameter

Nodejs mongoose Mass/Batch update from file

So i have a csv file containing my information, i need to do a mass add/update
exports.add_questions_from_file = function (file_path, surveyid, callback)
{
var U = [{}];
fs.readFile(file_path, 'utf8', function(err, data){
if (err){
console.log(err);
callback(err,null);
}else{
console.log(data);
d = data.split(/\r\n|\n/);
for (x=0;x <d.length;x++)
{
line = d[x].split(',');
if (line[0] == "") {return};
RQuestion.add_by_line (line,function (err, question)
{
U.push({id:question.id});
console.log(U);
});
}
}
});
Survey.update({_id:surveyid},{$push:{"SurveyQuestions":U}},function (err,numAffected, rawResponse) {
console.log(rawResponse);
RET = {"module":"survey","operation": "add", "status":"OK"};
callback(RET);
});
};
But even though im using callback functions the update seems to happen with the same object always, even the console.log here
U.push({id:question.id});
console.log(U);
returns the same object (even that all the other were created)
Im doing something wrong?
I see a few issues.
First for:
if (line[0] == "") {return};
Don't you mean to use a break or continue instead? Otherwise the entire function will quit if there is a blank line anywhere in the file. This is very important because Survey.update won't get called either.
Second: I assumed that RQuestion.add_by_line and Survey.update are doing something async like updating a database. Your code needs to be restructured to wait for those async items to complete before moving on to the next step. I'd recommend an npm package named async for that.
fs.readFile(file_path, 'utf8', function(err, data){
if (err){
console.log(err);
callback(err,null);
}else{
d = data.split(/\r\n|\n/);
async.map(d, function(line, callback) {
//this function is called for each line
add_by_line (line,function (err, question)
{
callback(err,{id:question.id});
});
}, function(err, results) {
//this function is called when all of the items are done
console.log("done with async");
console.dir(results);
Survey.update({_id:surveyid},{$push:{"SurveyQuestions":results},function (err,numAffected, rawResponse) {
console.log(rawResponse);
RET = {"module":"survey","operation": "add", "status":"OK"};
callback(RET);
});
});
}
});

Categories

Resources