Express - MySQL conn.end() is not functioning (Cannot enqueue after invoking quit) - mysql

I have already read the post Node Mysql Cannot Enqueue a query after calling quit, the conn.end() is in my query block.
My issue is that conn.end in my dashboard.js does not work and breaks the app with the following error.
I need to use it because MySQL connections are flooding the system till Database stop accepting more of them since they all stay open each time that are used.
For this post I will use only one (dashboard.js) of the several routes of my NodeJS application.
`Event.js` is not a part of my working files, probably is a file from `./node_modules`
|events.js:183
throw er; // Unhandled 'error' event
^
Error: Cannot enqueue Quit after invoking quit.
at Protocol._validateEnqueue (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\Protocol.js:204:16)
at Protocol._enqueue (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\Protocol.js:139:13)
at Protocol.quit (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\Protocol.js:92:23)
at Connection.end (E:\NodeJS\Project-Change\node_modules\mysql\lib\Connection.js:249:18)
at ServerResponse.res.end (E:\NodeJS\Project-Change\node_modules\express-myconnection\lib\express-myconnection.js:114:54)
at ServerResponse.send (E:\NodeJS\Project-Change\node_modules\express\lib\response.js:191:8)
at fn (E:\NodeJS\Project-Change\node_modules\express\lib\response.js:896:10)
at View.exports.renderFile [as engine] (E:\NodeJS\Project-Change\node_modules\ejs\lib\ejs.js:323:3)
at View.render (E:\NodeJS\Project-Change\node_modules\express\lib\view.js:76:8)
at Function.app.render (E:\NodeJS\Project-Change\node_modules\express\lib\application.js:527:10)
at ServerResponse.res.render (E:\NodeJS\Project-Change\node_modules\express\lib\response.js:900:7)
at Query._callback (E:\NodeJS\Project-Change\routes\dashboard.js:39:17)
at Query.Sequence.end (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\sequences\Sequence.js:88:24)
at Query._handleFinalResultPacket (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\sequences\Query.js:139:8)
at Query.EofPacket (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\sequences\Query.js:123:8)
at Protocol._parsePacket (E:\NodeJS\Project-Change\node_modules\mysql\lib\protocol\Protocol.js:279:23)
app.js (only relative lines)
var express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
app = express(),
expressValidator = require('express-validator'),
session = require('express-session'),
passport = require('passport'),
flash = require('connect-flash'),
passportConfig = require('./config/passport'),
dbConfig = require('./config/db');
// skipping code about static files, bodyparser, expressValidator, session, passport
passportConfig(passport)
/*MySQL connection*/
var connection = require('express-myconnection'),
mysql = require('mysql');
app.use(
connection(mysql, dbConfig,'request')
);
var dashboard = require('./routes/dashboard.js'); // in this route I apply conn.end()
var router = require('./routes/rates.js');
// skipping app.post/app.get code for /login & /logout & isLoggedIn middleware
app.use('/', router);
app.use('/', dashboard); // issue on that
app.get('/',function(req,res){
res.render('./dashboard.ejs'); //issue on that
});
module.exports = app;
routes/dashboard.js (route)
var express = require('express');
var router = express.Router();
var dashboard = express.Router();
dashboard.use(function(req, res, next) {
console.log(req.method, req.url);
next();
});
var dashboard = router.route('/');
//show the CRUD interface | GET
dashboard.get(function(req,res,next){
req.getConnection(function(err,conn){
if (err) return next("Cannot Connect");
var query = conn.query('SELECT SUM(total_price) AS transactions_total FROM transactions WHERE date_created = CURDATE(); SELECT SUM(total_profit) AS total_profit FROM transactions', function(err,rows){
if(err){
console.log(err);
return next("MySQL error, check your query");
}
var ab = {data:rows[0]};
var total_profit = {data:rows[1]};
res.render('dashboard',{ab, total_profit});
conn.end(); // causes the described error
});
// conn.end(); even tried here
});
});
dashboard.all(function(req,res,next){
console.log("route for dashboard executed");
console.log(req.params);
next();
});
module.exports = router;
console.log('dashboard.js loaded!');
config/db.js
module.exports = {
host : 'localhost',
user : 'root',
password : '',
database : 'mydb',
multipleStatements: true,
debug : false
}
config/passport.js
External presentation in case is needed here

Related

React.js + Express: how to run SQL requests implying several databases?

I am currently working on the API of a React.js project. I have no trouble running SQL requests with databases on MySql servers using Express as long as the SQL request only implies a single database.
My problem: I now have to run an SQL request which implies using data from several databases and I do not know how to do it.
What I currently do in my server.js file to run SQL on a single database:
...
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const mysql = require('mysql');
...
let sql = "";
...
// *************************
// CLIENT & DB CONFIGURATION
// *************************
const app = express();
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var server = app.listen(3001, "127.0.0.1", function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
});
app.use(cors());
const connection = mysql.createConnection({
host : 'myhost.fr',
user : 'someone',
password : 'aZefdt%',
database : 'SuiviTruc',
multipleStatements : true
});
connection.connect(function(err) {
if (err) throw err
console.log('You are now connected with SuiviTruc database...')
});
// **************
// Request sample
// **************
app.get('/SelectAffaire_',(req, res) => {
let sql=`SELECT * FROM t_Affaire_;`
connection.query(sql, (error, result)=> {
if (error) throw error;
res.send(result);
})
})
Thanks for your help!

how to use mysql in node.js all app files?

Hello mates, first, I hope everyone is in good health.
Sorry if this question is a little confuse, but i'm trying creating a API/webservice that works with MySql, so I have
in root (/) the file bd.js with the connection
bd.js:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'skey-9'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
then i add to /app.js and have the routes of diferente directories
app.js:
const express = require('express');
const app = express();
const morgan = require('morgan');
const bodyParser = require('body-parser');
const db = require('./bd');
const productRoutes = require('./api/routes/products');
const orderRoutes = require('./api/routes/order');
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json());
//Routes
app.use('/products', productRoutes);
app.use('/orders', orderRoutes);
in the final i'm trying to query a Select in /routes/products.js
products.js:
const express = require('express');
const router = express.Router();
var db = require('./../bd');
con.connect((err) => {
if(err){
console.log('Error connecting to Db');
return;
}
console.log('Connection established');
});
con.query('SELECT * FROM teste', (err,rows) => {
if(err) throw err;
console.log('Data received from Db:');
console.log(rows);
});
router.get('/', (req, res, next) => {
res.status(200).json({
message: 'handling GET requests to / products',
query: rows
});
});
module.exports = router;
but i'm getting a error i already tried to "playing" with the bd files.
the error:
C:\NODE\node-rest\server.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957:15)
at Function.Module._load (internal/modules/cjs/loader.js:840:27)
at Module.require (internal/modules/cjs/loader.js:1019:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object.<anonymous> (C:\NODE\node-rest\api\routes\products.js:3:10)
at Module._compile (internal/modules/cjs/loader.js:1133:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
at Module.load (internal/modules/cjs/loader.js:977:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Module.require (internal/modules/cjs/loader.js:1019:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\NODE\\node-rest\\api\\routes\\products.js',
'C:\\NODE\\node-rest\\app.js',
'C:\\NODE\\node-rest\\server.js'
]
My question is how can i do a "global" mysql connection to all the app I'm creating.
soo i have 2 subpath's, and for some reason i had to change
var db = require('./../bd'); "
to
var db = require('..\\..\\bd'); "
forget this dont resolve my problem, we have to run a connection to all the router's?

How to connect sql server to app.js file?

I have a folder called NEsql, located in a folder called sqlnames1. Inside the NEsql folder, I have the following files.
sqlcreatedb.js
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
/*Create a database named "mydb":*/
con.query("CREATE DATABASE names", function (err, result) {
if (err) throw err;
console.log("Database created");
});
});
sqlcreatetable.js
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "names"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
/*Create a table named "customers":*/
var sql = "CREATE TABLE people (id INT AUTO_INCREMENT PRIMARY KEY, firstName VARCHAR(255), lastName VARCHAR(255))";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("Table created");
});
});
sqlinsertvalues.js
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "names"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
var sql = "INSERT INTO people (firstName, lastName) VALUES ?";
var peoplenames = [
['Vedant', 'Apte'],
['Vedant', 'Savalajkar'],
['Vinay', 'Apte'],
['Varda', 'Apte'],
['Mihir', 'Wadekar'],
['Mihir', 'Kulkarni'],
['Eesha', 'Hazarika'],
['Eesha', 'Gupte'],
['Raunak', 'Sahu'],
['Hritvik', 'Agarwal'],
['Mahima', 'Kale'],
['Shivani', 'Sheth'],
['Arya', 'Chheda'],
['Diya', 'Shenoy']
];
con.query(sql, [peoplenames], function (err, result) {
if (err) throw err;
console.log("Number of records inserted: " + result.affectedRows);
});
});
All of these files work, as I am able to complete all the tasks and successfully receive all the corresponding console.log statements. However, I am unsure as to how I am supposed to connect these files to the app.js file located inside the sqlnames1 folder. Anyone know how to do this?
Here is my app.js file.
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
What you're trying to do could simply just be the content of the app.js file you could require your package there and run these functions. However if going that route is what you choose it you could store them in a variable and then use a module.export like so
variable_name = [desired content to export]
module.export = variable_name
If you'd like to go about building a database through separate files than your app.js you should look at the package sequelize. This is more along the lines of you're trying to do.
https://www.npmjs.com/package/sequelize
Responding to your comment if you are trying to build a db upon running app.js. You are again better off looking at an ORM of some sort that will do it better than the mysql package. With it you can import the db to your app.js and simply use
require('path to db')
then using the db how you see fit, but again building your db in this way will be difficult to do as you would have to run
node filename.js
for every single one, so again if not sequelize i would strongly recommend looking at another ORM that will get this job done for you much faster and easier. As soon as you run your app.js it will build and then run, the mysql package is not the best tool to use for what it seems you are trying to do.

Angular 4 - display date from database

I need display data in table from MySql database, but I dont know how it do this.
I tried found something example or example application with source code, but I nothing found.
Maybe someone help me with this?
I tried with node.js express:
var mysql = require('mysql');
var https = require('https');
var con = mysql.createConnection({
host: "https://adress to database",
user: "user",
password: "password",
database: "db"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
But i get error:
Error: getaddrinfo ENOTFOUND
here is a simple way to get data from mySQL and export it as json:
var http = require('http');
var mysql = require('mysql');
var bodyParser = require("body-parser");
var express = require('express');
var app = express();
var pool = mysql.createPool({
host: 'db location',
user: 'username od db',
password: 'something',
database: 'yourdatabase',
port:3306
});
// define rute
var apiRoutes = express.Router();
var port = 9000;
apiRoutes.get('/', function (req, res) {
res.json({ message: 'API works' });
});
apiRoutes.get('/data', function (req, res, next) {
pool.getConnection(function (err, connection) {
if (err) {
console.error("error hapened: " + err);
}
var query = "SELECT * FROM imena ORDER BY id ASC";
var table = ["imena"];
query = mysql.format(query, table);
connection.query(query, function (err, rows) {
connection.release();
if (err) {
return next(err);
} else {
res.json({
success: true,
list_users: rows
});
}
});
});
});
app.use('/api', apiRoutes);
// starting
app.listen(port);
console.log('API radi # port:' + ' ' + port);
But i still suggest that you start using noSQL databases like firebase because of they are simple and faster.
In order to show data from MySQL Database, you need to provide application interface(s) to Angular environment and only then Angular can use the data. There are few techniques in which you can design interfaces, REST is the most popular though.
First you need to understand that Angular is Front-End framework and it can only send requests to backend such as Node js, PHP etc.Thus, first you need to chose your backend. Node is popular with express js module, but if you still don't have mySQL set, go for firebase real time database. If you decide node js => express => mySQL check tutorial online.

Node JS Error: write after end

In the following code, I am trying to retrieve data from MySQL database and show them to a user by using response write. The error that I got is Error: write after end:
var http = require("http");
var mysql = require('mysql');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.use(express.static('public'));
app.get('/Search.html', function (req, res) {
res.sendFile( __dirname + "/" + "Search.html" );
})
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : 'somepass',
database : 'SocialQuery',
}
);
connection.connect();
app.post('/process_post', urlencodedParser, function (req, res) {
// Prepare output in JSON format
response = {
SearchType:req.body.SearchTypes,
Term:req.body.term
};
//var vas = JSON.stringify(response);
var search = req.body.SearchTypes;
var term = req.body.term;
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
res.write(rows);
});
console.log(query.sql);
res.end();
})
//}).listen(8081);
http.createServer(app).listen(8081);
console.log('Server running at http://127.0.0.1:8081/');
I changed res.write(rows); to res.end(rows); but didn't work. Can someone help me solving this problem.
The problem is that MySQL queries are asynchronous in node.js. so, the result won't be in the variable query, but retrieved in the callback, to the variable rows. So what happens is that res.end() is called, and then the callback returns and res.write() is called, so it's called after end().
You are doing an Asynchronous call when fetching data from database. res.write() is inside callback function so before fetching data it would call res.end() and res.write() will be called after the data has been fetched. That's why you are getting Error: write after end . You can use res.end() in the same callback function.
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
res.write(rows, function(err){
res.end();
});
});
Now the res.end() function will be called after the write process has been done.
It worked after I made two changes:
var query = connection.query('Select * from ?? where Lable = ?', [search, term], function(err, rows) {
console.log(rows);
res.write(JSON.stringify(rows));
res.end();
});
First, I moved res.end(); inside the connection.query part.
Second, instead of writing rows only, I changed to res.write(JSON.stringify(rows));