node js - Node mysql - Result is undefined - node.js

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

Related

Correct way to get a value from mongodb?

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

Incorrect order execution on my server TCP (node.js)

I attached my server code:
var net = require('net');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('MyBBDD.db');
var prueba = '';
function get_kw_actual(nombre,callback){
stmt = db.prepare("SELECT kw_actual FROM usuarios WHERE usuario = ?");
stmt.bind(nombre);
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
}
var server = net.createServer(function(socket) {
console.log("Recibo peticion");
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
prueba = '' + resultado;
})
socket.write(prueba);
});
socket.on('close', function () {
console.log('Connection closed');
});
});
server.listen(1337, '192.168.1.101');
In my server, I receive a request, I call to my function "get_kw_actual" I get a number of my database and finally I respond with the result.
The problem is that it runs first "socket.write(prueba);" than:
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
So... the execution is not executed in the correct order and the result is not correct.
Somebody know how can I solve it?
Thanks in advance.
Best regards.
Node.js code runs asynchronously. The code in the callback get_kw_actual returns immediately but the callback will run at some later time, when the database operation has completed. What you want to do is put socket.write inside of the callback, like this:
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
socket.write(resultado);
})
});
Also note that you're using a global variable prueba in your code, which will get clobbered when you have multiple clients running against your server. Do not use global variables like this in node.

Unable to post via express using bodyparser

I have a web app containing four routes out of which two are executing insert query in Postgresql and two are executing select query. The post in insert is working fine but post in select query is not working. Is this problem of the query or post i'm unable to understand. Printing the post var gives undefined. Please help.
ws.post('/prab',function(req,res){
var vill = req.body.addr;
console.log(vill);
if(!(vill = null) )
{
pg.connect(conString,function(err,client,done){
if(err){
return console.error('Could not connect to postgres' , err);
}
var results = [];
var query = client.query("SELECT * FROM \"Area_info\" WHERE \"FOLDER_NAME = $1",[vill],function(err,result){
console.log(vill);
console.log(query);
query.on('row', function(row) {
results.push(row);
});
query.on('end', function() {
done();
return res.json(results);
});
if(err) {
return console.error('error running query', err);
}
else{
if(results.length == 0)
{
res.render('abs');
}
else{
res.render('re');
}
}
})
})
}
});
I solved my problem. It was silly on my part as i picked bootstrap template , i forgot to change the type of button from button to input. Thanks everybody to help me and waste your precious time on my silly mistake. I would be careful from next time.
This might be your problem:
if(!(vill = null) )
You're doing an assignment to vill and not the equality operator (== or ===). The assignment operator according to the Node REPL returns whatever is on the right hand side which in this case is null. Therefore, the statement (!(vill=null))above will always evaluate to true.

How to properly return a result from mysql with Node?

In the code
var stuff_i_want = '';
stuff_i_want = get_info(parm);
And the function get_info:
get_info(data){
var sql = "SELECT a from b where info = data"
connection.query(sql, function(err, results){
if (err){
throw err;
}
console.log(results[0].objid); // good
stuff_i_want = results[0].objid; // Scope is larger than function
console.log(stuff_i_want); // Yep. Value assigned..
}
in the larger scope
stuff_i_want = null
What am i missing regarding returning mysql data and assigning it to a variable?
============ New code per Alex suggestion
var parent_id = '';
get_info(data, cb){
var sql = "SELECT a from b where info = data"
connection.query(sql, function(err, results){
if (err){
throw err;
}
return cb(results[0].objid); // Scope is larger than function
}
==== New Code in Use
get_data(parent_recording, function(result){
parent_id = result;
console.log("Parent ID: " + parent_id); // Data is delivered
});
However
console.log("Parent ID: " + parent_id);
In the scope outside the function parent_id is null
You're going to need to get your head around asynchronous calls and callbacks with javascript, this isn't C#, PHP, etc...
Here's an example using your code:
function get_info(data, callback){
var sql = "SELECT a from b where info = data";
connection.query(sql, function(err, results){
if (err){
throw err;
}
console.log(results[0].objid); // good
stuff_i_want = results[0].objid; // Scope is larger than function
return callback(results[0].objid);
})
}
//usage
var stuff_i_want = '';
get_info(parm, function(result){
stuff_i_want = result;
//rest of your code goes in here
});
When you call get_info this, in turn, calls connection.query, which takes a callback (that's what function(err, results) is
The scope is then passed to this callback, and so on.
Welcome to javascript callback hell...
It's easy when you get the hang of it, just takes a bit of getting used to, coming from something like C#
I guess what you really want to do here is returning a Promise object with the results. This way you can deal with the async operation of retrieving data from the DBMS: when you have the results, you make use of the Promise resolve function to somehow "return the value" / "resolve the promise".
Here's an example:
getEmployeeNames = function(){
return new Promise(function(resolve, reject){
connection.query(
"SELECT Name, Surname FROM Employee",
function(err, rows){
if(rows === undefined){
reject(new Error("Error rows is undefined"));
}else{
resolve(rows);
}
}
)}
)}
On the caller side, you use the then function to manage fulfillment, and the catch function to manage rejection.
Here's an example that makes use of the code above:
getEmployeeNames()
.then(function(results){
render(results)
})
.catch(function(err){
console.log("Promise rejection error: "+err);
})
At this point you can set up the view for your results (which are indeed returned as an array of objects):
render = function(results){ for (var i in results) console.log(results[i].Name) }
Edit
I'm adding a basic example on how to return HTML content with the results, which is a more typical scenario for Node. Just use the then function of the promise to set the HTTP response, and open your browser at http://localhost:3001
require('http').createServer( function(req, res){
if(req.method == 'GET'){
if(req.url == '/'){
res.setHeader('Content-type', 'text/html');
getEmployeeNames()
.then(function(results){
html = "<h2>"+results.length+" employees found</h2>"
html += "<ul>"
for (var i in results) html += "<li>" + results[i].Name + " " +results[i].Surname + "</li>";
html += "</ul>"
res.end(html);
})
.catch(function(err){
console.log("Promise rejection error: "+err);
res.end("<h1>ERROR</h1>")
})
}
}
}).listen(3001)
Five years later, I understand asynchronous operations much better.
Also with the new syntax of async/await in ES6 I refactored this particular piece of code:
const mysql = require('mysql2') // built-in promise functionality
const DB = process.env.DATABASE
const conn = mysql.createConnection(DB)
async function getInfo(data){
var sql = "SELECT a from b where info = data"
const results = await conn.promise().query(sql)
return results[0]
}
module.exports = {
getInfo
}
Then, where ever I need this data, I would wrap it in an async function, invoke getInfo(data) and use the results as needed.
This was a situation where I was inserting new records to a child table and needed the prent record key, based only on a name.
This was a good example of understanding the asynchronous nature of node.
I needed to wrap the all the code affecting the child records inside the call to find the parent record id.
I was approaching this from a sequential (PHP, JAVA) perspective, which was all wrong.
Easier if you send in a promise to be resolved
e.g
function get_info(data, promise){
var sql = "SELECT a from b where info = data";
connection.query(sql, function(err, results){
if (err){
throw err;
}
console.log(results[0].objid); // good
stuff_i_want = results[0].objid; // Scope is larger than function
promise.resolve(results[0].objid);
}
}
This way Node.js will stay fast because it's busy doing other things while your promise is waiting to be resolved
I've been working on this goal since few weeks, without any result, and I finally found a way to assign in a variable the result of any mysql query using await/async and promises.
You don't need to understand promises in order to use it, eh, I don't know how to use promises neither anyway
I'm doing it using a Model class for my database like this :
class DB {
constructor(db) {
this.db = db;
}
async getUsers() {
let query = "SELECT * FROM asimov_users";
return this.doQuery(query)
}
async getUserById(array) {
let query = "SELECT * FROM asimov_users WHERE id = ?";
return this.doQueryParams(query, array);
}
// CORE FUNCTIONS DON'T TOUCH
async doQuery(queryToDo) {
let pro = new Promise((resolve,reject) => {
let query = queryToDo;
this.db.query(query, function (err, result) {
if (err) throw err; // GESTION D'ERREURS
resolve(result);
});
})
return pro.then((val) => {
return val;
})
}
async doQueryParams(queryToDo, array) {
let pro = new Promise((resolve,reject) => {
let query = queryToDo;
this.db.query(query, array, function (err, result) {
if (err) throw err; // GESTION D'ERREURS
resolve(result);
});
})
return pro.then((val) => {
return val;
})
}
}
Then, you need to instantiate your class by passing in parameter to constructor the connection variable given by mysql. After this, all you need to do is calling one of your class methods with an await before. With this, you can chain queries without worrying of scopes.
Example :
connection.connect(function(err) {
if (err) throw err;
let DBModel = new DB(connection);
(async function() {
let oneUser = await DBModel.getUserById([1]);
let allUsers = await DBModel.getUsers();
res.render("index.ejs", {oneUser : oneUser, allUsers : allUsers});
})();
});
Notes :
if you need to do another query, you just have to write a new method in your class and calling it in your code with an await inside an async function, just copy/paste a method and modify it
there are two "core functions" in the class, doQuery and doQueryParams, the first one only takes a string as a parameter which basically is your mysql query. The second one is used for parameters in your query, it takes an array of values.
it's relevant to notice that the return value of your methods will always be an array of objects, it means that you'll have to do var[0] if you do a query which returns only one row. In case of multiple rows, just loop on it.

module always returns null no matter what

I am new to node.js and was wondering why my code always return null.
I have db.js
exports.getItems = function(){
var conn = mysql.createConnection();
conn.connect();
conn.query("Select * From Items", function(err, rows, fields) {
if (err) throw err;
conn.end();
return rows;
});
};
and the module is called like this:
var db = require('../db.js');
exports.items = function(req, res){
var data = db.getItems();
console.log('second', data);
res.end(data);
};
and route:
app.get('/api/items', api.items);
The console.log('second') is always "second undefined". I have verified that the query is return items in the rows.
Please advice.
Classic async problem.
getItems is going to return before the database query is done. The data from the database is returned in the callback, not in the function itself.
When you write:
var data = db.getItems();
console.log('second', data);
res.end(data);
the value for data is undefined because you don't have a return statement inside getItems! So getItems returns undefined, as per the rules of JavaScript.
What you need is something like (and please understand I have not tested this) is:
exports.items = function(req, res){
var conn = mysql.createConnection();
conn.connect();
conn.query("Select * From Items", function(err, rows, fields) {
conn.end();
if (err) throw err;
res.end(rows);
});
}
See various sites online for managing connections cleanly. But this should be enough to get you to understand that the response should be sent from the callback of query which is where the data is actually available.

Resources