Why is it showing connection not defined? - javascript

I'm trying to use connection from a connection.js file and use it in different file webFrontend.js using exports object. Now what I get on running server is:
{
"Result": "undefinedThis is result"
}
That means connection is not defined. Why is it happening? connection is working fine if getConnection is created in same (webFrontend.js) file, but the problem is when I use getConnection in same exports function in connection.js hence the connection not defined error:
Here are 2 necessary files (routes file has no problem) that explains what I'm doing:
connection.js
var mysql = require('mysql');
exports.connExport = function () {
var connectionPool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '',
database: 'rockcity_followme'
});
if(connectionPool) {
connectionPool.getConnection(function (err, connection) {
if (err) {
return err;
} else {
return connection;
}
});
}else{
var abc="return error";
return abc;
}
}
webFrontend.js
var connObj=require('../Routes/connection.js');
var connection=connObj.connExport();
exports.getIndivRecords= function(req, res, next){
res.send({
Result: connection+"This is result"
});
return next();
};

No need for the .js file extension, it's automagically added for you.
The code below uses standard error-first callbacks
webFrontend.js
var connection = require('../Routes/connection');
exports.getIndivRecords = function(req, res, next){
// connection takes a standard error-first callback
connection(function(err, conn){
if (err) {
// Handle the error returned
console.log(err);
}
// The database connection is available here as conn
console.log( "Connection:" + conn);
// presumably you want to do something here
// before sending the response
res.send({
Result: conn + "This is result"
});
});
return next();
};
connection.js
var mySQL = require('mysql');
var connectionPool = mySQL.createPool({
host: 'localhost',
user: 'root',
password: '',
database: 'rockcity_followme'
});
var getConnection = function (cb) {
connectionPool.getConnection(function (err, connection) {
// pass the error to the callback
if (err) {
return cb(err);
}
cb(null, connection);
});
};
module.exports = getConnection;

First of all #Dan Nagle was right no need of .js
Second You are getting the connection undefinded because still the method doesnt returned with result.
Use promise to call your Connection.js method
Your node is single threaded async execution,
He doest wait for the method to return a result
1) Problem with your javascript is that
var connection=connObj.connExport();
in Creation stage connection was defined by javascript as undefined and as
connObj.connExport(); as still not returned with answer
it executed this function in which connection was undefined
exports.getIndivRecords= function(req, res, next){
res.send({
Result: connection+"This is result"
});
Use promise read this first so you can understand something about promise and callback if you are unable to solve than comment i will play with it.But first you try.Thanku
Understanding promises in node.js
Ok Try This I have used promise here
var connObj = require('../Routes/connection');
connObj.connExport().then(
function (connection) {
exports.getIndivRecords = function (req, res, next) {
res.send({
Result: connection + "This is result"
});
return next();
};
}).catch(function (err) {
res.status(400).send(err);
return;
});
var mysql = require('mysql');
exports.connExport = function () {
return new Promise(function (fulfill, reject) {
var connectionPool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '',
database: 'rockcity_followme'
});
if (connectionPool) {
connectionPool.getConnection(function (err, connection) {
if (err) {
return reject(err);
} else {
return fulfill(connection);
}
});
} else {
var abc = "return error";
return reject(abc);
}
});
}

Related

How to use .then method for promises with mySQL?

I know that mongodb has their own way of handling native promises with no rejection issues but I guess it doesnt work the same here with mysql. Is there anyway I can use .then in mysql? I was able to do it using more callbacks but I would like to use promises to make the solution cleaner or even use async/await if that makes it simpler too. I need to use a callback to jump to my server file, I have all my methods defined in my db file.
Server file:
app.get('/api/cows', (req, res) => {
db.reqMethods.getAll((err, data) => {
if (err) {
res.send('Error');
} else {
res.send(data);
}
});
});
db file:
const mysql = require('mysql');
const http = require('http');
const express = require('express');
const path = require('path');
const bodyParser = require("body-parser");
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'cowlist'
});
connection.connect((err) => {
if (err) {
console.log(err);
} else {
console.log('Connected to MySQL!')
}
});
// Your Database Queries Here!!
module.exports.reqMethods = {
// GET All Cow Info
getAll: function (callback) {
const query = connection.query('SELECT * FROM cows;');
query.then(data => callback(null, data));
});
};
// callback solution that I'd like to simplify:
// getAll: function (callback) {
// connection.query('SELECT * FROM cows;', (err, data) => {
// if (err) {
// callback(err, null);
// } else {
// console.log("DATA: \n", data);
// callback(null, data);
// }
// });
// }
Yes, this is possible by using mysql2 npm package.
So in your database.js file, use this method.
const mysql = require('mysql2');
var pool_connection = mysql.createPool({
host: '127.0.0.1',
port: 3306,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 10,
multipleStatements: true
});
pool_connection.getConnection((err) => {
if (err) console.log(JSON.stringify(err));
else {
console.log('Connected!')
}
});
module.exports = pool_connection.promise();
And in your models, you require the connection as follows and make use of async-await in a try-catch block.
const con = require('/path/to/your/database_file');
module.exports = class Messages {
constructor() { }
static async getMessage(arguments_here) {
const query = "some query here with params if required. Use ? for placing params and do not use string literal to embed params.";
try {
const [response] = await con.execute(query, [params]);
return response;
} catch (error) {
console.log(error);
return null;
}
}
}
And in your controller,
const Messages = require('../models/Messages');
const someFn = async (req, res) =>{
try {
const result = await Messages.getMessages('sample_arguments');
//do something with result
}
catch(err){
console.log(err);
}
}

Getting mysql result from javascript function in node.js

I am trying to get MySQL to result from the function.
At moment I am trying to set results from function to global array, but this doesn't work.
I am not very familiar with NodeJS or Javascript but I think it's a scope issue.
How would one do this in a proper way? Do I need to use async or maybe return results from a function?
This is what I have at moment.
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'xxxx',
port : '3306',
user : 'xxxx',
password : 'xxxx',
database : 'xxxx'
});
var db_members =[];
get_members();
console.log(db_members); //outputs []
function get_members(){
connection.query("SELECT * FROM users", (err, result, fields)=>{
if (err) throw err;
result.forEach(function(row) {
db_members.push(row.username);
});
console.log(db_members); //this works
});
}
connection.query is async function so you are not able to get the result synchronously.
It is needed to make get_members to return Promise as the return value so to get the result asyncronously when using it..
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'xxxx',
port : '3306',
user : 'xxxx',
password : 'xxxx',
database : 'xxxx'
});
function get_members() {
return new Promise((resolve, reject) => {
connection.query("SELECT * FROM users", (err, result, fields)=>{
if (err) return reject(err);
var db_members = [];
result.forEach(function(row) {
db_members.push(row.username);
});
return resolve(db_members);
});
});
}
get_members()
.then((members) => {
console.log(members); // This will work.
})
.catch((error) => {
console.error(error);
});

How to organize communication with database in Node.Js?

I have a problem to design communication with MySQL database in my Nodejs's app.
The biggest problem is that queries are async, so it becomes complicated to design my projects. For example, I have excercises.js
EXCERCISES.JS
var express = require('express');
var database = require('../database/database.js');
var router = express.Router();
console.log(database.db(saveDbData))
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('exercises',{title: 'Exercises', ex: #DATABASE RESULT});
});
module.exports = router;
In need to write query's result in ex field.
Then I write a module to handle mysql connection
DATABASE.JS
var pool = mysql.createPool({
connectionLimit: 10000,
host: 'localhost',
user: 'root',
password: 'password',
database: 'Example'
});
var results;
var db = function(){
pool.query('SELECT name FROM Exercises', function(error, results, fields){
if (error) throw error;
res = results;
})
return res;
}
module.exports = {
db: db,
}
Obviously, It doesn't work because pool.query is async.
The only alternative that I've found on the web is something like this:
EXERCISES.JS
var pool = mysql.createPool({
connectionLimit: 10000,
host: 'localhost',
user: 'root',
password: 'password',
database: 'Example'
});
pool.query('SELECT name FROM Exercises', function(error, results, fields){
if (error) throw error;
router.get('/', function(req, res, next) {
res.render('exercises',{title: 'Exercises', ex: result[0].name});
});
})
But in this way, mysql parts and routing/render parts are mixed. Is it still a well-designed solution? Are there more elegant solutions?
EDIT:
I have modified the files and I have used Promise like this
EXERCISES.JS
var express = require('express');
var database = require('../database/database.js');
var router = express.Router();
var data = database.db()
.then(
function(data){
console.log("Resolved");
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('exercises',{title: 'Exercises', ex: data[0].name});
});
})
.catch(
error => console.error(error));
module.exports = router;
DATABASE.JS
ar mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit: 10000,
host: 'localhost',
user: 'root',
password: 'password',
database: 'Example'
});
var res;
var db = function(){
return new Promise(function(resolve, reject){
pool.query('SELECT name FROM Exercises', function(error, results, fields){
if (error) reject(error);
resolve(results)
})
})
}
module.exports = {
db: db,
}
And it works, but I don't think it is the best solution. For example, what if I want to get data for render from more queries?
I'm new in these technologies so I'm not able to figure out the best way to integrate database and html pages's rendering.
Have you ever wondered why all web frameworks in node requires you to return responses using the res object instead of just return? It's because all web frameworks expect that you need to do something asynchronous.
Consider a web framework design similar to Laravel (PHP) or Spring Framework (Java):
// Theoretical synchronous framework API:
app.get('/path', function (request) {
return "<html><body> Hello World </body></html>";
});
Then if you need to do anything async you will face the issue that the data you're fetching hasn't returned by the time you need to return the HTTP request:
// Theoretical synchronous framework API:
app.get('/path', function (request) {
return ??? // OH NO! I need to return now!!
});
It is for this reason that web frameworks in javascript don't act on return values. Instead it passes you a callback to call when you are done:
// Express.js
app.get('/path', function (request, response) {
doSomethingAsync((err, result) => {
response.send(result);
});
});
So for your code you just need to do:
router.get('/', function(req, res) {
pool.query('SELECT name FROM Exercises', function(error, results, fields){
if (error) throw error;
res.render('exercises',{title: 'Exercises', ex: result[0].name});
});
});
Exporting the database
Exporting the database is as simple as exporting pool:
db.js
var pool = mysql.createPool({
connectionLimit: 10000,
host: 'localhost',
user: 'root',
password: 'password',
database: 'Example'
});
module.exports = {
pool: pool
}
exercises.js
let db = require('./db');
// you can now use db.pool in the rest of your code
// ..
Reusing your queries
Instead of coding SELECT statements in your controllers (routes) you can (and should) code them in your db module(s):
db.js
var pool = mysql.createPool({
connectionLimit: 10000,
host: 'localhost',
user: 'root',
password: 'password',
database: 'Example'
});
function getExerciseNames (callback) {
pool.query('SELECT name FROM Exercises',callback);
}
module.exports = {
pool: pool
}
Then in your controller logic you just need to do:
router.get('/', function(req, res) {
db.getExerciseNames(function(error, results, fields){
if (error) throw error;
res.render('exercises',{
title: 'Exercises',
ex: result[0].name
});
});
});
Caching
If your intention is to query the db only once to cache the value of Exercises then don't invert the Express routing flow. Instead implement the caching at your db layer:
db.js:
var exerciseNamesCache = [];
var exerciseNamesFields = [];
function getExerciseNames (callback) {
if (exerciseNamesCache.length > 0 && exerciseNamesFields.length > 0) {
callback(null, exerciseNamesCache, exerciseNamesFields);
}
pool.query('SELECT name FROM Exercises',function(error, results, fields){
if (!error) {
exerciseNamesCache = results;
exerciseNamesFields = fields;
}
callback(error, results, fields);
});
}
Promises
Promises is a design pattern for handling callbacks. It is comparable to Java's Futures (CompletionStage etc.) only a lot more lightweight. If an API you are using returns a promise instead of accepting a callback then you need to call res.render() inside the promise's .then() method:
router.get('/', function(req, res, next) {
doSomethingAsync()
.then(function(result){
res.send(result);
})
.catch(next); // remember to pass on asynchronous errors to next()
});
If the API you're using accepts a callback then weather or not you wrap it in a promise is more a matter of taste. I personally wouldn't do it unless you are also using another API that returns a promise.
async/await
One advantage of promises is that you can use them with await. Express specifically works well with async/await. Just remember you can only use await inside a function marked with async:
router.get('/', async function(req, res, next) {
let result = await doSomethingAsync();
res.send(result);
});
Multiple asynchronous operations
Fetching multiple asynchronous data can be as simple as:
router.get('/', function(req, res, next) {
doSomethingAsync(function(result1){
doSomethingElse(function(result2) {
res.json([result1, result2]);
});
});
});
With promises that would be:
router.get('/', function(req, res, next) {
doSomethingAsync()
.then(function(result1){
return doSomethingElse()
.then(function(result2) {
return [result1, result2];
});
})
.then(function(results){
res.json(results);
})
.catch(next);
});
But both the above code perform the requests sequentially (get result1 then get result2). If you want to fetch both data in parallel you can do this with Promises:
router.get('/', function(req, res, next) {
Promise.all([
doSomethingAsync(), // fetch in parallel
doSomethingElse()
])
.then(function(results){
res.json(results);
});
})
With callbacks it's a little bit more complicated. There is a design pattern you can use and someone has actually implemented it as a library called async.js but often the easiest solution is to wrap them in Promises and use Promise.all(). Still, do check out async.js since it has functionality useful for things like batching requests, perform async operations while a condition is true etc. (the promise based counterpart of that library is async-q)
You can use npm modules for achieving the async task with MySQL.
I recommended to choose sequilize or jm-ez-mysql. If you go with jm-ez-mysql then your code structure like
server.js
require('./config/database.js');
./config/database.js
const sql = require('jm-ez-mysql');
// Init DB Connection
const connection = My.init({
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASSWORD,
database: process.env.DATABASE,
dateStrings: true,
charset: 'utf8mb4',
timezone: 'utc',
multipleStatements: true,
});
module.exports = {
connection,
};
After that, you can use MySQL asynchronously.
./exercise.js
const sql = require('jm-ez-mysql');
const exerciseUtil = {};
exerciseUtil.searchUserById = async (id) => {
try {
// table name, db fields, condition, values
const result = await sql.first('users', ['id, name, email'], 'id = ?', [id]);
return result; // Which return your result in object {}
} catch (err) {
console.log(err);
throw err;
}
};
module.exports = exerciseUtil;
I hope it helps.
Happy Coding :)

What is the correct way to be using the Node.js MySQL Library?

Currently I am playing around with the MySQL library in Node.js however I have a question about the correct/most efficient way to be using this library.
According to w3schools the correct way to make a single query is to use code like this
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
However, say I wanted to make multiple queries which would be executed by an event for example how would I handle this? Should I create an "initialise" function which is executed as soon as the program runs such as this?
var mysql = require('mysql');
var database;
//Initialise database
function setupDatabase() {
database = mysql.createConnection({
host: token.host,
user: token.user,
password: token.password,
database: token.database,
port: token.port
});
}
//Imagine this could be called at any time after execution
function event() {
if(database != null) {
database.connect(function(err) {
if (err) throw err;
database.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
}
}
And also do I have to connect to the database each time I make a query or can I add the "database.connect" call to my setupDatabase function such as this?
var mysql = require('mysql');
var database;
//Initialise database
function setupDatabase() {
database = mysql.createConnection({
host: token.host,
user: token.user,
password: token.password,
database: token.database,
port: token.port
});
if(database != null) {
database.connect(function(err) {
if (err) throw err;
});
}
}
//Imagine this could be called at any time after execution
function event() {
if(database != null) {
database.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
}
}
My main concern is that calling the con.connect function every single time I make a query would be slow and although these are asynchronous I want to be using the correct/most efficient way possible. Feel free to correct me on any mistakes with the last two code snippets I have only tested the first one so far.
You have to make database connection only once per application livetime (unless you have disconnects). Then you may have as much queries as you want.
Just put database connection routine somewhere in sepparate file and then require it in your applicatin initialisation step.
// mysql.js
const mysql = require('mysql');
module.exports = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
Or require it anywhere you need database connection - it will return connected database object without reruning that code again and again.
// inex.js
const databse = require('./mysql')
database.query("SELECT * FROM customers")
I created a file which include a function that holds a pool and handles the connection to the database like this
let _this = {};
let POOL = null;
function getPool() {
return new Promise((resolve, reject) => {
if(POOL != null) {
resolve(POOL);
} else {
//create connection pool
POOL = connectionPool;
resolve(POOL);
}
});
}
function closePool(){
// close pool here
}
_this.getPool = getPool;
_this.closePool = closePool;
module.exports = _this;
Now you can call getPool() and will recive a pool of connections where you can execute your queries with.

Undefined query function

so I'm currently using the following code to execute queries;
var mysql = require('mysql');
var config = require('./config');
var pool = mysql.createPool(config.mysql);
function query(statement){
return new Promise(function(resolve, reject){
pool.getConnection(function(err, connection) {
if(err) reject(err);
connection.query(statement, function(err, row){
connection.release();
if(err){
reject(err);
}
resolve(row);
})
});
});
}
module.exports = {
pool: pool,
query: query
};
Whenever the query function is called it results in a undefined error;
TypeError: Cannot read property 'query' of undefined
I'm quite out of ideas why this could be, this would be connection.getConnection is not returning a proper connection, would this mean my credentials are wrong in my createPool function?
config.mysql
mysql: {
host: 'localhost',
user: 'root',
password: '',
database: 'site',
connectionLimit : 10,
multipleStatements : true
}
The problem is on the following line you are passing in the query function when you should be passing in a string.
connection.query(query, function(err, row){
query in that case should be a string. But you defined query as a function (function query(){)
If you change the line to something LIKE the following this should work.
connection.query("SELECT * from Users", function(err, row){

Categories