Got connect ECONNREFUSED node - mysql

I develop with mates for school a nodejs website. But I have this problem when I npm start.
I have been looking for few times a solution but find anything working for us.
Here is the error we get:
read: [Function],
secret: undefined,
cookies: { 'jenkins-timestamper-offset': '-7200000' },
signedCookies: {},
route:
{ path: '/question',
stack: [ [Object], [Object], [Object] ],
methods: { post: true, put: true, delete: true } } }
connect ECONNREFUSED
I just pick the last few lines because there are too many to copy/paste.
Here is my index.js file:
var express = require('express');
var mysql = require("mysql");
var md5 = require('MD5');
var router = express.Router();
var app=express();
var bodyParser = require("body-parser");
var questionList = [];
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
router.get("/ListQuestion",function (req,res){
client.query('SELECT * from question',function (err,results) {
res.render('ListQuestion', {listeQuestion: results});
})
});
/* GET home page. */
router.get('/', function(req, res) {
res.status(200).render('index', { title: 'Web-Service' });
});
router.get('/answer/:URI', function(req, res) {
var client=mysql.createConnection({
host : '172.17.0.2',
user : 'root',
password : 'rootroot',
database : 'questionreponse'
});
client.query('SELECT * from question WHERE answer !="NULL" AND uri= "'+req.params.URI+'" GROUP BY answer ORDER BY answer DESC' , function (error, results) {
console.log(results);
if (results && results[0] && results[0].answer && results[0].answer!=''){
res.status(200).render('answer', {answer: results[0].answer});
console.log(results[0].answer);
}else{
Same as before I cant copy the whole file because too long, if you need specific lines you can ask for.
If you have any solution to make it work I will take it.
Thanks in advance. :)

Related

In node.js, How to return mysql results from a function?

I tried to separate function to another file, as the function fetching data from mysql database.
This is db.js
const mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "sample"
});
con.connect()
module.exports = function(query) {
con.query(query, function (err, result) {
if (err){
console.log(err);
} else{
console.log(result)
return result
}
});
};
This is main.js
const express = require('express')
const db = require('./db')
const app = express()
app.get('/test', function(req, res){
var sql = "SELECT id FROM user"
console.log(db(sql))
res.send(db(sql))
});
In main.js on console.log(db(sql)) got undefined.
But in db.js on console.log(result) I got the values as:
[
RowDataPacket { id: 1 },
RowDataPacket { id: 2 },
RowDataPacket { id: 3 }
]
Why did I get undefined in the main.js? Is there any solution for this issue?
Since you are using callback function, you can't directly return the value from it.
you have 2 options to do what you want to do.
Promise
Async/Await (mysql2 module needed)
Try this,
Querying
function(query) {
return new Promise((resolve, reject) =>{
try{
con.query(query, function (err, result) {
if (err){
return reject(err)
}
return resolve(result)
});
}
catch(e){
reject(e)
}
})
};
Main
app.get('/test', async function(req, res){
var sql = "SELECT id FROM user"
try{
const userId = await db(sql)
return res.send({
success: true,
result: {
userId
}
})
}
catch(e){
console.error(e)
return res.status(500).send({
success: false,
message: 'internal server error'
})
}
})
One more thing, if you have a good reason to write query by yourself, you can use
knex for making it easier (https://www.npmjs.com/package/knex), which is a query builder, meaning doing nothing to do with database connection.
Sollution
Try async/await with mysql2
Dont go for mysql2/primse because it will cause unexpected errors when your database is in the cloud or deployed somewhere like clearDB addons provided by Heroku
Follow these steps...
create config file for your database connection seperately
import mysql from 'mysql2'
let db = mysql.createPool({
host: 'your host name',
user: "your username",
password: "your password",
database: "your database name",
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
})
export { db }
execute the query the same like this i am doing
import {db} from 'where you defined the above db config'
app.get('/test', async function(req, res){
const promise= db.promise()
var sql = "SELECT id FROM user"
const [rows,field] = awiat promise.execute(sql)
res.send(rows)
});

What am I missing? I want to store my session to MySQL database

I have my database up and running. The connection is working. I want to store my session in to the database.
Here's my code. When I run the server on my browser I get this error:
RequestError: No connection is specified for that request.
I just kept it simple in one app.js file.
var express = require('express');
var mysql = require('mysql2');
var session = require('express-session');
var MsSQLStore = require('mssql-session-store')(session);
var port = 3000;
var app = express();
var connection = mysql.createConnection ({
host: 'localhost',
user: 'root',
password: '.....',
database: 'node'
});
var sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
var options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
if(app.get('env') === 'production') {
app.set('trust proxy', 1)
sess.cookie.secure = true
}
app.use(session(sess));
connection.connect();
connection.query('Select 1 + 1 AS solution', (err, rows, fields) => {
if (err) throw err
console.log('the solution is: ', rows[0].solution)
});
app.listen(port, (req, res) => {
console.log('the server is running, ' + ' please, open your browser at http://localhost:%s', port);
});
app.get('/', (req, res) => {
res.end('Hello World');
});
In store: new MsSQLStore(options), you are attempting to use options before you've assigned it a value so it will be undefined when you try to use it. Move the definition and assignment of options to BEFORE you use it.
So, change this:
var sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
var options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
to this:
const options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
const sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
Incidentially, if you use let or const for these, then this would have been flagged by the interpreter as an error which is yet another reason to stop using var entirely.

ENOENT: no such file or directory, stat '/Users/sampai/Desktop/Repos/task_tracker/task_tracker/build/index.html'

So I am trying to create my backend routes for my full stack MERN application (with mysql). My application uses sequelize as my ORM and when I tried writing the get route for getting the data out of the database, this error comes up
"ENOENT: no such file or directory, stat '/Users/sampai/Desktop/Repos/task_tracker/task_tracker/build/index.html' "
Below is my get request in my controller file.
module.exports = function(router) {
router.get("/api/tasks", (req, res) => {
db.Task.findAll({}).then(data => {
res.json(data);
});
});
}
Below is my server.js file
const express = require("express");
const app = express();
const path = require("path");
const PORT = process.env.PORT || 3000;
const db = require("./models");
app.use(express.static(path.join(__dirname, "build")));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.get("ping", function (req, res) {
return res.send("pong");
})
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "build", "index.html"));
})
require("./controllers/taskController")(app);
db.sequelize.sync().then(function() {
app.listen(PORT, () => {
console.log("Your API server is now on PORT:", PORT);
})
})
And lastly, below is my sequelize model
const Sequelize = require("sequelize");
module.exports = function(sequelize, DataTypes){
var Task = sequelize.define("Task", {
id: {
type: Sequelize.INTEGER(11),
allowNull: false,
autoIncrement: true,
primaryKey: true
},
task: DataTypes.STRING
});
return Task;
}
Can anyone help me figure out why I am getting this error? Thanks!
ACtually I figured it out, I just got rid of that app.get with the build, index.html statement in the server.js and it worked!

Express session not saving after successful authentication

I am implementing a login system for my project. This project is divided in two, a server portion in NodeJS, and a client portion in ReactJS. Both of these are wrapped up in docker containers including a couple more containers for mySQL and PHPMyAdmin. Thus far, I've been able to connect to databases in the mySQL container and insert into a table for Users. Now, I'm trying to log in with a user, then save this user information if the login is successful, and return the session when asked. So I call the sign in get request as follows in the front-end:
export function signIn(table, userName, password) {
return axios.get(`http://localhost:8000/signin`, {
params: {
table,
userName,
password,
},
}, {withCredentials: true}).then((response) => {
if (response.data.length === 1) {
return "success";
}
return response;
});
}
Then in the server, I receive and work with the information like this:
const bcrypt = require('bcryptjs');
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const multer = require('multer');
const mysql = require('mysql');
const nodeMailer = require('nodemailer');
const session = require('express-session');
const smtpTransport = require('nodemailer-smtp-transport');
const app = express();
const upload = multer();
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000,
secure: false,
}
}));
app.use(cors(({
credentials: true,
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const pool = mysql.createPool({
host: process.env.MYSQL_HOST_IP,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
});
app.get('/signin', (req, res) => {
const { table, userName, password } = req.query;
pool.query(`select * from ${table} where username = '${userName}'`, (err, results) => {
if (err) {
res.send(err);
} else {
if (bcrypt.compareSync(password, results[0].password)) {
req.session.userId = results[0].id;
req.session.name = results[0].name;
req.session.email = results[0].email;
req.session.sex = results[0].sex;
req.session.img = results[0].img;
req.session.userName = results[0].username;
req.session.about = results[0].about;
req.session.save(err => console.log(err));
res.send(results);
} else {
res.send([]);
}
}
});
});
Then I expect to call it with another request to get the information back and use to to modify a front end component's state like this (both of these requests are in the same file):
app.get('/loggeduser', (req, res) => {
if (req.session.userId) {
const {
userId,
name,
email,
sex,
img,
userName,
about,
} = req.session;
const userInfo = {
userId,
name,
email,
sex,
img,
userName,
about,
};
res.send(userInfo);
} else {
res.send({});
}
});
and the component calls it like this:
export function getLoggedUser(setUserInfo) {
axios.get(`http://localhost:8000/loggeduser`, {}, {withCredentials: true}).then((response) => {
setUserInfo(response.data);
});
}
But the information never gets sent back, because req.session.userId is always undefined. I tried adding a console.log to output req.session and whenever I refresh the page (at which time the component calls getLoggedUser) the server image outputs req.session with a created time that is just a few seconds ago from the moment I refresh the page, meaning it gets created anew whenever I refresh. Is it that this is not saving properly because it's a get request and not a route? Please let me know if I may be missing something vital for this to work.

Node.js MySQL model designing

I'm developing a node.js application using MySQL database but I'm stuck with making models on the node.js side of my application. I've used Mongoose before to produce schemas and use models to do database functions but i couldn't find such support for MySQL. Can anyone suggest a proper way to isolate my database functions in node.js like I could do with Mongoose. here's my app.js and users model i'm using right now.
app.js
var express= require("express");
var bodyParser = require("body-parser");
var mysql = require("mysql");
var UserModel= require("./models/User.js")
var app=express();
var sql = mysql.createConnection({
host: "localhost",
user: "root",
password: "1234",
database: "dricm"
});
sql.connect(function (err) {
if(err){
console.log("error");
}else{
console.log("connected");
}
});
app.set("views", "./views");
app.use(express.static("node_modules/bootstrap/dist"));
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.get('/', function (req, res) {
res.render("signup.jade");
});
app.post('/signup', function (req, res) {
var obj= {
username: req.body.username,
password: req.body.password
};
UserModel.createUser(obj);
res.redirect("/");
});
app.listen(3000, function () {
console.log("server running at 3000");
});
User.js (probable model)
var mysql= require("mysql");
var bcrypt = require("bcryptjs");
var sql = mysql.createConnection({
host: "localhost",
user: "root",
password: "1234",
database: "dricm"
});
sql.connect(function (err) {
if(err){
console.log("error");
}else{
console.log("connected");
}
});
var User= {
}
User.createUser = function createUser(newUser) {
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.password,salt, function (err, hash) {
newUser.password = hash;
var query = sql.query("INSERT INTO USERS set ?", newUser, function (err, res) {
console.log(query);
if(err) {
console.log("error");
}
else{
console.log(res.insertId);
}
});
});
});
}
module.exports= User;
What you are looking for is called an ORM (Object-relational mapping) Mongoose is one for MongoDB (Which is a NOSQL document oriented database)
There are other ORMs for relational databases that work with Node.js, The most popular right now is Sequelize which I have personally used and recommend.
With Sequelize you can put your models in different files just like Mongoose however in order to load them on, you need to add them with a simple script inside your index.js
Imagine the following Workspace:
--models/
----User.js
----Permissions.js
--index.js
And your model definitions should be something like this:
User.js
const UserModel = (sequelize, Sequelize) => {
const {INTEGER, STRING, FLOAT, BOOLEAN, DATE} = Sequelize
const User = sequelize.define('User', {
UserId: {type: INTEGER, primaryKey: true, autoIncrement: true},
Username: {type: STRING, primaryKey: true, allowNull: false},
Password: STRING
})
return User
}
module.exports = UserModel
Permissions.js
const PermissionsModel = (sequelize, Sequelize) => {
const {INTEGER, STRING, FLOAT, BOOLEAN, DATE} = Sequelize
const Permissions = sequelize.define('Permissions', {
Role: {type: STRING, allowNull: false},
ControllerAddress: {type: STRING, allowNull: false}
})
return Permissions
}
module.exports = PermissionsModel
Now you need to use the following script to use them inside your index.js
let normalizedPath = require('path').join(__dirname, "models")
require('fs').readdirSync(normalizedPath).forEach((file) => {
sequelize.import('./models/' + file)
})
let {User, Permissions} = sequelize.models
Now you can use the User and Permissions instances to control them and call functions like:
User.create({Username, Password})