Correct way to get a value from mongodb? - node.js

I am using mongodb and mysql with my nodejs.
employee.find({status:1}, function(error,response) {
for(i=0;i<=response.length;i++){
var fileid = response[i]._id;
var sql = "SELECT * FROM EMPLOYEE WHERE `id` = '"+fileid+"'";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Result: " + result);
});
}
})
The above code gives me the exact record and result but in my logger file i am getting the below error everytime,But i have no problem in getting my output.I am using winston to record my service logs. The main reason why i am worrying about this error is my node js APi's are going down more or less after every 8 hours and my databases are not going idle(using forever npm module to run my service forever) and so i am believing that this might be the reason for killing my node processess. Below is my error.Any help?
"stack":["TypeError: Cannot read property '_id' of undefined"(var fileid = response[i]._id;)]

Because i should be less than response.length. array length is always greater than the last index.
For example,
var arr = [1,2]; //length is 2 and last index value is 1
Change you code like this: for(i=0;i<response.length;i++)
employee.find({status:1}, function(error,response) {
for(i=0;i<response.length;i++){
var fileid = response[i]._id;
var sql = "SELECT * FROM EMPLOYEE WHERE `id` = '"+fileid+"'";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Result: " + result);
});
}
})

Related

node js how to sort a collection

I have a mongodb collection which has a large quantity of entries. + 10000.
All of these have the same paramters:
Val_string
T1_string
T2_string
I am receiving this via a get request from my mobile app however the order is not correct.
How can I sort my collection by the Val string which is a number going from 1 to 10000 in this case.
I am using mongoose mongodb and node js.
Presently I query the collection and get 5 results send them and then loop another 5 until I have read all the results.
So I need to sort the collection out prior to sending this data.
app.get("/testmethod", function(req, res)
{
mongoose.connect("mongodb://localhost:27017/CTI", {useNewUrlParser: true},function(err, client){
if(err) {
console.log(err)
}
else
{
client.db.collection("datas").find().limit(items_to_send).skip(Sent_data).toArray(function(err, result) {
if (err) {throw err;}
//console.log(result);
Sent_data = Sent_data + items_to_send;
db.close();
var D1_T1 = result[0].T1_String;
var D1_T2 = result[0].T2_String;
var D2_T1 = result[1].T1_String;
var D2_T2 = result[1].T2_String;
var D3_T1 = result[2].T1_String;
var D3_T2 = result[2].T2_String;
var D4_T1 = result[3].T1_String;
var D4_T2 = result[3].T2_String;
var D5_T1 = result[4].T1_String;
var D5_T2 = result[4].T2_String;
res.status(200).send({
D1_T1: D1_T1,
D1_T2: D1_T2,
D2_T1: D2_T1,
D2_T2: D2_T2,
D3_T1: D3_T1,
D3_T2: D3_T2,
D4_T1: D4_T1,
D4_T2: D4_T2,
D5_T1: D5_T1,
D5_T2: D5_T2
});
});
}//End of else
});//End of connect
});
What I want is a sort to order the entire collection by the val string field which goes from 1-10000
You have as below
client.db.collection("datas").find().limit(items_to_send).skip(Sent_data)
You can add .sort({fieldName:sortOrder})
sort order: 1 / -1(desc)
client.db.collection("datas").find().limit(items_to_send)
.skip(Sent_data).sort({"val_string":1})
Sort follows lexicographical order so no problem of being string.

Why is my select statement returning old data after a working update statement?

I run the code below on my express server. My goal is to update the database then, query the updated table. Everything is working except the query does not return updated results. If I run it a second time it returns the correct results for the first update.
//// Run Update
var db = new sqlite3.Database(myFile);
var UpdateStatement = "UPDATE Employees SET Firstname = '"+Firstname+"', Lastname = '"+Lastname+"' WHERE id = "+ID+";";
db.run(UpdateStatement);
db.close();
//// Query table
var SELECTSTATEMENT = "SELECT * FROM Employees ;";
db = new sqlite3.Database(scheduleFile);
db.all(SELECTSTATEMENT,[],(err, rows) => { if (err) { console.log("error at get /db.all Select "); throw err; }
var strArr = JSON.stringify(rows);
response.send(strArr);// Does not send back updated results.
db.close();
});
Im guessing the database variable is still stale even after I create a new variable?
//create sql statement and bind the parameters
var db = new sqlite3.Database(myFile);
var UpdateStatement = "UPDATE Employees SET Firstname = ?, Lastname = ? WHERE id = ?;";
// run statement and get the callback once its done
db.run(UpdateStatement,[firstName, lastName, id], function(err){
// if err occured return the error
if(err)
return err
// else return the response
var SELECTSTATEMENT = "SELECT * FROM Employees ;";
db = new sqlite3.Database(scheduleFile);
db.all(SELECTSTATEMENT,[],(err, rows) => { if (err) { console.log("error at get /db.all Select "); throw err; }
var strArr = JSON.stringify(rows);
response.send(strArr);// Does not send back updated results.
db.close();
});
});

Function to return data from SQLite3 query in node.js

I'm making a bot for Discord, and one of the features in this bot is a level system. I've decided to go from using JSON to store the data, to sqlite. I'm using sqlite3 in node.js and am trying to create a function to create / retrieve a player's data. My goal is to make this function return the data from the query, but I'm running my head into a brick wall trying to figure out what I'm doing wrong. I've read that I need to use callbacks sent to the query function, but that has not worked for me either (nor will it work for the goal of this function).
So any help on how I can create a function to return the data from the query would be extremely helpful! This is the code I have so far before I've given up and decided to come here for help before I lose any more hair. Everything else is working as I intend, I am just unable to retrieve the data from the db.each().
exports.getPlayerData = function(players,msg,mention = false){
if(mention){
// console.log("mention found");
var member = msg.mentions.users.first();
} else {
var member = msg.member.user;
};
var db = new sqlite3.Database('data/levels/' + msg.guild.id + '.db');
var check;
db.serialize(function() {
var stmt = "CREATE TABLE if not exists uid_" + member.id + " (id INTEGER PRIMARY KEY, username TEXT, avatarID TEXT, avatarURL TEXT, xp INTEGER, level INTEGER, lastXp INTEGER)";
db.run(stmt);
db.run("INSERT OR IGNORE INTO uid_" + member.id + " (id,username,avatarURL,xp,level,lastXP) VALUES (?,?,?,?,?,?)", member.id,member.username, member.avatarURL , 0, 0, 0);
db.each("SELECT * FROM uid_" + member.id + " WHERE id = " + member.id , function(err, row) {
console.log(row);
return row;
});
});
// return row;
db.close();
}
If I understood your problem correctly, then you must be facing issue related to the placement of return statement. You want to return all rows, but aren't able to return, because of asynchronous nature of code.
I checked the documentation of sqlite3's .each, and found out that there exist complete callback that you can call after you have fetched all rows. In that callback, you can return data array that has collection of rows.
Update: You have to use callback
exports.getPlayerData = function(players,msg,mention = false, callback){
if(mention){
// console.log("mention found");
var member = msg.mentions.users.first();
} else {
var member = msg.member.user;
};
var db = new sqlite3.Database('data/levels/' + msg.guild.id + '.db');
var data = []; //for storing the rows.
db.serialize(function() {
var stmt = "CREATE TABLE if not exists uid_" + member.id + " (id INTEGER PRIMARY KEY, username TEXT, avatarID TEXT, avatarURL TEXT, xp INTEGER, level INTEGER, lastXp INTEGER)";
db.run(stmt);
db.run("INSERT OR IGNORE INTO uid_" + member.id + " (id,username,avatarURL,xp,level,lastXP) VALUES (?,?,?,?,?,?)", member.id,member.username, member.avatarURL , 0, 0, 0);
db.each("SELECT * FROM uid_" + member.id + " WHERE id = " + member.id , function(err, row) {
data.push(row); //pushing rows into array
}, function(){ // calling function when all rows have been pulled
db.close(); //closing connection
callback(data);
});
});
}
To have to pass callback to get player data.
getPlayerData(players, msg, false, function(data){
console.log(data);
});
Hope it works for you and saved your hair :). Let me know, if there are any issues.
You should go with wait.for npm.
More example can be found here: https://www.npmjs.com/package/wait.for
Sharing code which worked for me below you can find it :
var wait = req.app.get('wait');
wait.launchFiber(handleGet, req, res);
function handleGet(req, res)
{
var slashes = req.app.get('slashes');
var connection = req.app.get('connection');
var user_lib = req.app.get('user_lib');
var user_id = req.params.userId;
user_id = slashes.add(user_id);
var user_insert_id = wait.for(user_lib.update_user_status, connection, user_id);
res.render('view/email_verification', { req:req, res:res});
}
user code lib file :
Object.prototype.update_user_status=function (connection, cc_user_id, callback)
{
connection.query('update cc_user set cc_user_active="yes" where cc_user_id ="'+cc_user_id+'"',function(err,rows){
if(err) throw err;
if(rows)
{
return callback(err,{rows:rows});
}
});
}

Nodejs & Sqlite - Why each statement return no results

I'm trying to retrieve the data from Sqilte DB (using NodeJs).
I want to print into the log every row entry.
For some reason I'm not getting errors but I'm not getting results either.
I'm creating the DB in the following code:
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('usersDataBase');
db.run("CREATE TABLE IF NOT EXISTS usersTable (id INTEGER PRIMARY KEY AUTOINCREMENT , userName TEXT, password TEXT)");
db.close();
and adding users with the following code:
var db = new sqlite3.Database('usersDataBase');
var stmt = db.prepare("INSERT INTO usersTable VALUES (null, ?, ?)", userName, passw);
stmt.finalize();
db.close();
Finally I'm trying to print the table content with:
app.get("/view", function(req, res) {
var db = new sqlite3.Database('usersDataBase');
db.each("SELECT * FROM usersTable", function(err, row) {
if (err) console.log('Error: ' + err);
else console.log(row.userName + ": " + row.password)
//db.close();
});
//db.close();
// get to main screen
console.log('Sending main.html')
res.sendFile('main.html', {root: __dirname })
})
But I'm getting nothing on the screen. (No error message and no results)
What am I doing wrong ?
Can you please show the error, using the error object as following in one of the three operations :
var db = new sqlite3.Database('usersDataBase');
db.each("SELECT * FROM usersTable", function(err, row) {
if(err) console.error(err);
else console.log(row.userName + ": " + row.password);
});
a little hint may be out of topic:
Your set of queries might become very complex, so I suggest you to use the promise module, for promise mechanism, which might save you for latter time, and make your code more readable, when it becomes complex.
promise.denodeify transform a node callback style function into a promise, (methods whom callbacks have err and result arguments (the order is important)):
var promise = require('promise');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('usersDataBase');
var dbEach = promise.denodeify(db.each);
dbEach("SELECT * FROM usersTable")
.then(onSelectFromUsersTableSuccess)
.catch(onSelectFromUsersTableError);
function onSelectFromUsersTableSuccess(row) {
// handle row
}
function onSelectFromUsersTableError(err) {
// handle error
}

node js - Node mysql - Result is undefined

app.js
MyDatabase = require("./mysql");
...
var availableRooms = mydb.checkRoomStatus();
console.log("Rooms " + availableRooms);
//undefined.
mysql.js
MyDatabase.prototype.checkRoomStatus = function() {
this.con.query('SELECT * FROM rooms WHERE status = "open" LIMIT 1',function(err,rows){
if(err) throw err;
console.log('Data received from Db:\n');
console.log(rows); // results are coming here.
return rows;
});
}
The first console.log is outputting "undefined" for availableRooms variable.
I think i should use a callback function for this kind of request.
But i dont know how to use it. When i search in internet, i dont find anyone using separate file for mysql to get callback results.
You need to return callback(rows) to return your rows and you need to catch it in your callback. I hope it's clear. Try this out, and see if it works.
change your mysql code to
MyDatabase.prototype.checkRoomStatus = function(callback) {
this.con.query('SELECT * FROM rooms WHERE status = "open" LIMIT 1',function(err,rows){
if(err) throw err;
console.log('Data received from Db:\n');
console.log(rows); // results are coming here.
return callback(rows);
});
Now in app.js
MyDatabase = require("./mysql");
...
mydb.checkRoomStatus(function(res){
var availableRooms = res;
console.log("Rooms " + availableRooms);
});

Resources