[Global variable]Why my variable is undefined? - javascript

Can anyone tell me why I get an undefined MessageList in export function and how to get a correct value? The two blocks are in a same file.
var MessageList;
var sql = require("mssql");
var config = {
//config
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
var request = new sql.Request();
request.query('select top 3 * from test', function (err, recordset) {
if (err) console.log(err)
MessageList = JSON.stringify(recordset);
console.log("MessageList in sql.connect:"+MessageList); //===> that's ok
});
});
The Problem is here:
exports.getMessageList = function (callback) {
console.log("MessageList in exports:"+MessageList); // ===> **MessageList here will show undefine**
callback(MessageList);
};

Related

How to get the return value from Node.js function which contains DB query from another application

I'm learning Node.js and I'm just starting to work with some MySQL connections. I have a function which is supposed to get a set of rows from the database. However I can't get the value from it.
//connect.js
var mysql = require('mysql');
module.exports = {
world : function () {
var conn = mysql.createConnection({
host : '',
user : 'root',
password : '',
database : ''
});
conn.connect(function(err){
if(err) throw err;
});
conn.query('SELECT * FROM `room` WHERE 1', function(err, result, fields){
if(err) throw err;
var id = JSON.stringify(result[0].id);
var name = JSON.stringify(result[0].name);
var time = JSON.stringify(result[0].time);
return time;
});
conn.end(function(err){
if(err) throw err;
})
}
};
And I try to get the value by this program:
//show.js
var hello = require('./connect');
console.log(hello.world());
The result like this:
$ node show
undefined
So how should I get the value?
You cannot just return an asynchronous value inside your connect.js.
To return this value time, you have to pass by a callback function, or a promise.
This is an example of a callback :
//connect.js
var mysql = require('mysql');
module.exports = {
world : function (callback) { // Now world method takes a callback function parameter
var conn = mysql.createConnection({
host : '',
user : 'root',
password : '',
database : ''
});
conn.connect(function(err){
if(err) callback(err, null); // Callback an error
});
conn.query('SELECT * FROM `room` WHERE 1', function(err, result, fields){
if(err) callback(err, null); // Callback an error
else {
var id = JSON.stringify(result[0].id);
var name = JSON.stringify(result[0].name);
var time = JSON.stringify(result[0].time);
callback(null, time); // callback your response here
}
});
conn.end(function(err){
if(err) callback(err, null); // Callback an error
})
}
};
And this is how you can get the response
//show.js
var hello = require('./connect');
hello.world(function(err, response) {
if (err) throw err;
console.log(response);
});
I suggest you to learn more about Javascript asynchronous
Hope it helps.

Callback is not a function -manage asynchronous call Node js

I am reading files from ftp using the code below.
var JSFtp = require("jsftp");
var config = require('./config.json');
var FtpService = function () {};
// Connect to FTP
var Ftp = new JSFtp({
host: config.ftp.host,
port: config.ftp.port,
user: config.ftp.user,
pass: config.ftp.pass
});
FtpService.prototype.getFTPDirectoryFiles = function (callback) {
Ftp.list(config.ftp.FilePath, function(err, res) {
if(err){
console.log('File Listing Failed', err);
callback(null,err);
return;
}
else{
console.log(res);
callback(null,res);
}
});
};
FtpService.prototype.closeFtp = function () {
console.log('Disconnect to FTP');
};
module.exports = new FtpService();
Now i include this ftp service js file in my index.js as
var ftp = require('./ftpservice.js');
ftpfiles = ftp.getFTPDirectoryFiles();
console.log(ftpfiles);
getFTPDirectoryFiles returns the list of file. But if i call it via index.js i get undefined ftpfiles. This is because of the asynchronous nature of node js.
so i thought of adding callback but
I am getting the error Callback is not defined in function FtpService.prototype.getFTPDirectoryFiles
In this line:
ftpfiles = ftp.getFTPDirectoryFiles()
you are not passing the callback that that function requires and are trying to use a return value that the function does not return.
You need to do something like this:
var ftp = require('./ftpservice.js');
ftp.getFTPDirectoryFiles(function(err, ftpfiles) {
if (err) {
console.log(err);
} else {
console.log(ftpfiles);
}
});
You need to pass a callbackfunction in your function getFTPDirectoryFiles();
var ftp = require('./ftpservice.js');
var ftpFiles;
function setFtpFiles(err, res) {
if (err) throw err;
ftpFiles = res; // to use "ftpFiles" variable later
console.log(res);
}
ftp.getFTPDirectoryFiles(setFtpFiles);
1 Don't change args order to call callback. (replace callback(null,err); and callback(null,res); by callback(err,res);)
2 You need define a specifc function (your callaback) an give it to ftp.getFTPDirectoryFiles().
var JSFtp = require("jsftp");
var config = require('./config.json');
var FtpService = function () {};
// Connect to FTP
var Ftp = new JSFtp({
host: config.ftp.host,
port: config.ftp.port,
user: config.ftp.user,
pass: config.ftp.pass
});
FtpService.prototype.getFTPDirectoryFiles = function (callback) {
Ftp.list(config.ftp.FilePath, function(err, res) {
if(err){
console.log('File Listing Failed', err);
callback(err, res);
return;
}
else{
console.log(res);
callback(err, res);
}
});
};
FtpService.prototype.getFTPDirectoryFilesSimplify = function (callback) {
// no console.log, but very more simple !
Ftp.list(config.ftp.FilePath, callback);
};
FtpService.prototype.closeFtp = function () {
console.log('Disconnect to FTP');
};
and then :
var ftp = require('./ftpservice.js');
ftpfiles = ftp.getFTPDirectoryFiles(function(err,res){
// do your specifc job here using err and res
});
console.log(ftpfiles);

How to check if the db connection is success or not in node js and mysql

I'm using mysql connection pool to create connection. The code looks like the following.
var pool = mysql.createPool(connectionProps);
by accessing pool, I'll get the an Object, even if the connection is not Successful. I checked it with starting and stopping mysql.
What I want is that, I need to check connection is successful or not as follows.
if(pool){ // mysql is started && connected successfully.
console.log('Connection Success');
doSomething();
}else{
console.log('Cant connect to db, Check ur db connection');
}
I want something like this. So how can we do this with the mysql pool Object. Can someone please help me?
Thanks n Regards
Commonly you would do something like select something arbitrary from the db, and catch an error if that failed. Example from the docs.
const pool = mysql.createPool(connectionProps);
pool.query('SELECT 1 + 1 AS solution', (error, results, fields) => {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
var pool = mysql.createPool(config.db);
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
And require to use it like:
db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id)
.on('result', function (row) {
setData(row);
})
.on('error', function (err) {
callback({error: true, err: err});
});

Parsing JSON result from node oracledb

I am using oracledb with node and fetching data from it asynchronously. For the sake of ease, I have implemented it using separate files like below -
config.js -
module.exports = {
user : "user",
password : "password",
connectString : "*connstring*" ,
deliveredQuery: " SELECT COUNT (DISTINCT order_num) AS Cnt from orders where department = 'HR'
};
query2.js :
module.exports = function(callback) {//pass callback function and return with this
var oracledb = require('oracledb');
var dbConfig = require('./config.js');
this.queryDB = function(query,callback) {
oracledb.getConnection({
user: dbConfig.user,
password: dbConfig.password,
connectString: dbConfig.connectString,
deliveredQuery: dbConfig.deliveredQuery
}, function(err, connection) {
if (err) {
console.error(err.message);
return callback(err);
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
//console.log(result.metaData);
//console.log(JSON.parse(result.rows[0][0]));
doRelease(connection);
return callback(null, JSON.parse(result.rows[0][0]))
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
return callback(err);
}
});
}
};
};
serv_ontime.js :
var dbConfig = require('./config.js');
var res = require('./query2.js')();
var onTime_query = dbConfig.onTime_query;
module.exports = queryDB(onTime_query, function(err, callback){ });
index.js :
var res = require('./serv_ontime.js');
console.log("The result is= "+ res);
Now, When I am doing - node index.js from my cmd then I am getting the output as [object Object]. I suppose it is because the call is happening asynchronously. But if you see in the file query2.js , I am returning the value after parsing(using JSON.parse) but still the value I am getting in the index.js file is not the parsed one. How can I parse the value in index.js? I have already tried JSON.parse but it doesn`t work.
You are getting output as [object Object] because you are doing + with a String('The result is= '), So js engine tries to convert the Object to a String. To view it as an Object, do log it separately or log with comma separated,
console.log('The result is= ', res); (or)
console.log(res); // or console.dir(res)
Or you can get String version of it, by doing JSON.stringify(res)
console.log('The result is= ', JSON.stringify(res));
In serv_ontime.js you are exporting result of queryDB witch indeed is undefined. Ty this:
serv_ontime.js
var dbConfig = require('./config.js');
var res = require('./query2.js')();
var onTime_query = dbConfig.onTime_query;
module.exports = function (callback) {
queryDB(onTime_query, callback)
};
index.js
var serv_ontime = require('./serv_ontime.js');
serv_ontime(function(error, res) {
console.log("The error is= ", error);
console.log("The result is= ", res);
});

howto Node module.exports

I want to separate the code for executing mysql query in Node, so I am trying to use the Revealing Module pattern here
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
return _result = rows; <============
}
connection.release();
});
return;
});
console.log(_result);
return { recordSet : _result }
};
module.exports = sqlQuery;
How can I return rows to my app.js. the code below for calling sqlQuery is not working
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here').recordSet;
console.log(row);
res.json(rows);
Your code is asynchronous, but you're calling it synchronously.
If you wanted to do it like this, you'll also need to pass a callback to SqlQuery.
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString, callback) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
callback(rows);
}
connection.release();
});
});
};
module.exports = sqlQuery;
And then call it with:
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here', function(recordSet){
console.log(recordSet);
res.json(recordSet);
});
Edit: If you're using newer versions of JavaScript, you have a few more options.
If you have access to Promises, you can do this:
function sqlQuery (sqlString) {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) { return reject(err); } // error handling
connection.query(sqlString, function (err, rows) {
if (err) { return reject(err); }
resolve(rows);
connection.release();
});
});
});
}
module.exports = sqlQuery;
And then you'd use it like:
var SqlQuery = require(./path/to/sqlQueryFile);
SqlQuery('pass sql here')
.then(function(recordSet) {
console.log(recordSet);
res.json(recordSet);
})
.catch(function(err) {
// do your error handling
res.status(500).json({ err: 'Sorry there was an error' });
});
If you're using even newer JavaScript, you can use the async/await syntax (currently available via Babel, and I think in FireFox. Chrome in V55).
var SqlQuery = require(./path/to/sqlQueryFile);
async handleQuery(query) {
try {
var rows = await SqlQuery(query);
res.json(rows);
} catch (e) {
console.log('Error!', e);
}
}
To chain multiple queries together:
async handleQuery(query) {
try {
return await SqlQuery(query);
} catch (e) {
console.log('Error!', e);
}
}
var rows = await handleQuery('select * from tablename');
var rowsToReturn = await handleQuery('select id from another_table where name = "' + rows[0].name + '"');

Categories