Connect to MySql in node.js project with mvc architecture - mysql

I have a node.js project with mvc architectures,
I am trying to connect it to mysql database, and write a query,
I get the query result, but when I try to call the function that declare the query, I get an empty result,
I guess so it because of the query calling is async.
in my model:
exports.getAllUsers = function () {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
return result;
}
});
});
}
in my controller:
exports.get_all_users = function (req, res) {
var arr = UserModel.getAllUsers();
res.send(arr);
}
the arr in get_all_users function is always undefined,
what can be the problem???

There are three options you could use in node.js.
These are simple code for demo three style, they still have a lot space for improvement.
callback style
exports.getAllUsers = function (callback) {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
callback(result);
}
});
});
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers((result) => {
res.send(result);
});
}
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers().then(result) => {
res.send(result);
});
}
async-await style
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = async function (req, res) {
const result = await UserModel.getAllUsers();
res.send(result);
}

Related

how to return mysql query and an object

I need to return the MySQL query and an object from a function
when I try this code it works
const executeScript = (id, usersData, result) => {
db.query(`UPDATE users SET ? WHERE users_id=${id}`, usersData, (err, res) => {
if (err) {
result(null, err);
} else {
result(null, res);
}
});
};
executeScript(update(id, usersData), (err, results) => {
if (err) res.send(err);
res.json(results);
});
I need to use this format because of these functions is in different files
const update = (id, usersData) => {
return `UPDATE users SET ? WHERE users_id=${id}`, usersData;
};
const executeScript = (query, result) => {
db.query(query, (err, res) => {
if (err) {
result(null, err);
} else {
result(null, res);
}
});
};
executeScript(update(id, usersData), (err, results) => {
if (err) res.send(err);
res.json(results);
});

MySQL user-defined variables in Node.js mysql module

I was wondering whether MySQL user-defined variables will work using Node.js mysql module. The example below highlight exactly what I want to achieve using a transaction:
connection.beginTransaction(err => {
if (err) { throw err; }
connection.query('INSERT INTO user SET = ?', {id: 12, username: 'name'}, (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('SELECT #user_id:=userID FROM user WHERE username = ?', ['name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('INSERT INTO authentication SET `userID` = #user_id, ?', {password: 'userpassword'}, (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.commit(err => {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
});
You might be wondering, why not use the result of the second query in the third query. The transaction function is wrapped inside a utility function that accepts queries as an argument to be executed using transaction.
If the above code sample doesn't work, please is there a concise way to achieve this. Thank you.
After running the code sample it failed not because of MySQL variable in the second query. This code sample is what works for me:
connection.beginTransaction(err => {
if (err) { throw err; }
connection.query('INSERT INTO user (id, username) VALUES(?, ?)', [12, 'name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('SELECT #user_id:=userID FROM user WHERE username = ?', ['name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('INSERT INTO authentication (id, password) VALUES (#user_id, ?), ['userpassword'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.commit(err => {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
});

Do I need the promise in my MySQL statement?

Below is a MySQL statement in my Node.js app. I used a promise in MySQL function to get API endpoint to work. Is this a typical pattern for Node.js and MySQL?
const express = require('express');
const app = express();
app.use(express.static('client'));
const config = require('./config')
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.HOST,
user: config.USER,
password: config.PASSWORD,
database: config.DATABASE
});
function GetConsumers(req, res) {
return new Promise(function (resolve, reject) {
con.connect(function (err) {
if (err) throw err;
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) throw err;
//console.log(result);
resolve(result);
});
});
}).then(rows => res.send(rows));
}
app.get('/consumers', GetConsumers);
module.exports = app;
As George commented, you don't really need to return a promise here.
function GetConsumers(req, res) {
con.connect(function (err) {
if (err) {
res.send(err)
};
con.query("SELECT * FROM " + config.DATABASE + ".Contracts", function (err, result, fields) {
if (err) {
res.send(err)
};
//console.log(result);
res.send(result)
});
});
}
If you really want to use promises, it is always a good practice to catch the exceptions.
function GetConsumers(req, res) {
return new Promise(function (resolve, reject) {
con.connect(function (err) {
if (err){
reject(err);
}
con.query("SELECT * FROM " + config.DATABASE + ".Contracts",
function (err, result, fields) {
if (err){
reject(err);
}
//console.log(result);
resolve(result);
});
});
})
}
Call GetConsumers function where ever you want it.
GetConsumers(req,res).then(rows => res.send(rows))
}).catch(err =>{
console.log("Handle your error here");
res.send("error")
})
Mysql npm has good documentation of how to use the module. You can refer it more here

Return MySQL result after query execution using node.js

I want to return the MySQL result into a variable.
I tried the following but it's not working, as I am getting an empty variable.
const mysql = require('mysql');
const db = require('../config/db');
const connection = mysql.createConnection(db);
module.exports = class Categories {
constructor (res) {
this.res = res;
}
getCategories() {
connection.query("SELECT * FROM `categories`", (error, results, fields) => {
if (error) throw error;
this.pushResult(results);
});
}
pushResult(value) {
this.res = value;
return this.res;
}
};
Just made a callback function first:
var Categories = {
getCategories: function (callback) {
connection.query("SELECT * FROM `categories`", (error, results, fields) => {
if(error) { console.log(err); callback(true); return; }
callback(false, results);
});
}
};
And then used it with route:
app.get('/api/get_categories', (req, res) => {
categories.getCategories(function (error, results) {
if(error) { res.send(500, "Server Error"); return; }
// Respond with results as JSON
res.send(results);
});
});

encryption in node js

I tried to insert a encrypt value to db, i can encrypt the value the encrypted value can't be inserted in db.
app.post('/insert', function (req, res) {
// var Fname=req.body.fname;
// var Lname=req.body.pwd;
var data = {
Fname: req.body.fname,
Lname: req.body.Lname
};
function hashP(getit, cb) {
bcrypt.genSalt(15, function (err, salt) {
if (err) {
return console.log(err);
}
cb(salt);
bcrypt.hash(getit, salt, function (err, gotit) {
if (err) throw err;
return this.cb(null, gotit);
})
})
}
hashP(data.Lname, function (err, gotit) {
if (err) throw err;
data.Lname = hash;
})
console.log(data.Lname);
con.query("insert into test set ?", [data], function (err, rows) {
if (err) throw err;
res.send("Value has bee inserted");
})
})
This is my html form page:
<body>
<form action="http://localhost:8888/insert" method="POST" >
<label>Name:</label><input type="text" name="fname"></br>
<label>Lname:</label><input type="text" name="Lname"></br>
<button type="submit">Submit</button>
</form>
</body>
Seems like your function hashP(getit,cb) is calling cb function at bad time isn't it? try the following
function hashP(getit, cb){
bcrypt.genSalt(15, function (err, salt){
if(err) {
return cb(err, null);
}
bcrypt.hash(getit, salt, function (err, hash){
if(err) {
return cb(err, null);
}
return cb(null, hash);
})
})
}
Apart, you'll need to call it inside your handler as following:
app.post(...., function(req, res) {
var data = { ... }
function hashP(data, cb){ ... }
hashP(data.Lname, function (err, hash) {
if (err) throw err;
data.Lname = hash;
// NOW, SAVE THE VALUE AT DB
con.query("insert into test set ?", [data], function (err, rows) {
if (err) throw err;
res.send("Value has bee inserted");
})
}
}
The problem here was asynchronous execution, you were calling con.query with data before data is returned from hashP