Error : Crud using Nodejs express and Mysql - mysql

I'm facing an issue in my project I tried to do CRUD using MVC but when I run the code it doesn't return any data from db, the connection works fine I don't know why it doesn't work. I'm using NodeJS Express and mysql.
here is my code :
index.js:
db.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
const usersRouter= require("./routes/routes");
app.use("/api/", usersRouter)
routes.js:
// get latest record of airMonitoring
router.get("/", airController.getAllData);
Model.js:
const AirMonitoring = function(table){
this.id = table.id;
this.Temperature = table.Temperature;
this.Humidity = table.Humidity;
this.AirCondition = table.AirCondition;
}
// get all data from airMonitoring
AirMonitoring.getAllData = ( result) =>{
db.query('SELECT * FROM AirMonitoring', (err, res)=>{
if(err){
console.log('Error while fetching airMonitoring', err);
result(err, null);
}else{
console.log('AirMonitoring fetched successfully');
result(res, null);
}
})
}
Controller.js:
exports.getAllData = (req, res)=> {
AirModel.getAllData((err, airMonitoring) =>{
if(err)
res.send(err);
console.log('data', airMonitoring);
res.send(airMonitoring)
})
}
and the error received from postman :
error Console :

You need to return your res call in your if (err) statement. If you don't add a return it will proceed to execute the codes that follows.
if(err) return res.send(err);
Then again, your error stemmed from something before this.

Related

Node Api rest - change database dynamically|

Is it possible to change the pool config database?
I have a rest API with node/express, and I have multiple databases.
So I need that when a user.company login in my frontend, the API rest, choose the database that user should use.
My configuration file for the bank is this .env
JWT_KEY=XXXXXXX
POOL1_USER=root
POOL1_PASSWORD=xxxxxx
POOL1_DATABASE=data1
POOL1_HOST=host.domain.com
POOL1_PORT=3306
Meu arquivo db.js é este:
const mysql = require("mysql");
const pool1 = mysql.createPool({
connectionLimit: 10,
user: process.env.POOL1_USER,
password: process.env.POOL1_PASSWORD,
database: process.env.POOL1_DATABASE,
host: process.env.POOL1_HOST,
port: process.env.POOL1_PORT,
});
module.exports = { pool1 };
Is this my controllers.js file?
const mysql = require("../db").pool1;
exports.adminGroup = (req, res, next) => {
mysql.getConnection((error, conn) => {
if (error) {
return res.status(500).send({ error: error });
}
conn.query(
"INSERT INTO adminGroup SET ?",
[req.body],
(error, results) => {
conn.release();
if (error) {
return res.status(500).send({ error: error });
}
response = {
mensagem: "Group add",
grupoCriado: {
id: results.insertId,
grupo: req.body.group,
},
};
return res.status(201).send(response);
}
);
});
};
I need to dynamically change the database, as I have the same frontend for the same rest API, but I have multiple databases that can even be on different hosts.
It may be that what I'm trying to implement is not possible, so does anyone have any different suggestions?
Before you use the query to select a table from a database, you need to switch the database, use this query to achieve that.
con.query("USE your_db_name", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
then after it use the query that you want like this
const mysql = require("../db").pool1;
exports.adminGroup = (req, res, next) => {
mysql.getConnection((error, conn) => {
if (error) {
return res.status(500).send({ error: error });
}
con.query("USE your_db_name", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
conn.query(
"INSERT INTO adminGroup SET ?",
[req.body],
(error, results) => {
conn.release();
if (error) {
return res.status(500).send({ error: error });
}
response = {
mensagem: "Group add",
grupoCriado: {
id: results.insertId,
grupo: req.body.group,
},
};
return res.status(201).send(response);
}
);
});
};

Multiple Transactions in mysql for Node

I'm using node's driver for mysql and need to execute 'n' number of transactions one after the other and not simultaneously.
I've tried using a for/forEach loop but the transactions seem to happen concurrently and that causes my api to crash.Here's the error :-
throw err; // Rethrow non-MySQL errors
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
One single transactions seems to work just fine.
Each transaction has 4 queries, req.body is an array of objects:-
router.post('/production/add', (req, res) => {
for (const obj of req.body) {
pool.getConnection(function (err, connection) {
connection.beginTransaction(function (err) {
if (err) throw err;
const query1 = `select qty from production where prc_id = ${obj.prc_id}`;
console.log(query1);
connection.query(query1, function (error, result1, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ query: 1, message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const new_prod_qty = result1[0].qty - obj.auth_prod_qty;
const query2 = new_prod_qty > 0 ? `update production set qty = ${new_prod_qty} where prc_id = ${obj.prc_id}` : `delete from production where prc_id = ${obj.prc_id}`;
console.log(query2);
connection.query(query2, function (error, results2, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const query3 = `update prc set auth_prod_qty = ${obj.auth_prod_qty} where prc_id = ${obj.prc_id}`;
console.log(query3);
connection.query(query3, function (error, results3, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const query4 = "select * from store";
connection.query(query4, function (error, results3, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
connection.commit(function (err) {
if (err) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
res.status(201).send(results2);
});
});
});
});
});
});
});
};
});
Based off some research Sequelize ORM seems to promisify transactions but however I'm hoping to use it as a last resort. Any sort of solution with or without Sequelize would be appreciated!
Thanks in advance!
You need to use async / await to run your txs sequentially. How to do this?
Use npm mysql2 in place of npm mysql. That gets you promisified (awaitable) versions of the APIs when you require('mysql2/promise'). Plus, this is much more fun to program and debug than those miserable nested callbacks. Just don't forget the awaits.
Use this basic outline for your code's data processing loop. Everything will go in order sequentially. The way you create your pool is a little different; read the npm page. This is not debugged.
const mysql = require('mysql2/promise');
router.post('/production/add', async (req, res) => {
const connection = await pool.getConnection()
for (const obj of req.body) {
try {
await connection.beginTransaction()
const query1 = 'whatever'
const result1 = await connection.query(query1)
const query2 = 'something else'
const result 2 = await connection.query(query2)
/* etcetera etcetera */
await connection.commit()
}
catch (error) {
await connection.rollback()
pool.releaseConnection()
res.status(400).send({ something })
}
}
pool.releaseConnection()
}
mysql2/promise is exactly the package I was looking for, works with mysql and uses promise() method to upgrade mysql connection to a promise based mysql2 connection.
router.post('/stock/add', async (req, res) => {
const connection = pool.getConnection(async function (err, connection) {
if (err) {
connection.release();
res.status(400).send(err);
return;
}
else {
for (const obj of req.body) {
try {
await connection.promise().beginTransaction();
const [result1, fields1] = await connection.promise().query(query1)
const [result2, fields2] = await connection.promise().query(query2);
const [result3, fields3] = await connection.promise().query(query3);
const [result4, fields4] = await connection.promise().query(query4);
await connection.promise().commit();
}
catch (error) {
await connection.promise().rollback();
connection.release();
res.status(400).send(error);
return;
}
}
res.status(200).send('Transaction Complete');
}
});
});

NodeJs Restful Api Using MySQl

I have tried it through MongoDB, but I can't to use JOIN Query in mongoDB and my project is wide enough. So, Want to Create Restful API in node js in MySQL.
Can anyone suggest the solution
For creating REST API you can go with express JS
var express = require('express');
var app = express();
app.get('/', function (req, res) {
//BELOW-CODE
});
You can connect Mysql by following this code:
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);
);
});
Note: Install expressJS framework to get started
Happy coding :-)
For MySQL with NodeJS you can use Sequelize, it's an ORM kinda like doctrine in symfony
http://docs.sequelizejs.com/
`'user strict';
var sql = require('./db.js');
//Task object constructor
var Task = function(task){
this.task = task.task;
this.status = task.status;
this.created_at = new Date();
};
Task.createTask = function createUser(newTask, result) {
sql.query("INSERT INTO tasks set ?", newTask, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
Task.getTaskById = function createUser(taskId, result) {
sql.query("Select task from tasks where id = ? ", taskId, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
result(null, res);
}
});
};
Task.getAllTask = function getAllTask(result) {
sql.query("Select * from tasks", function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
console.log('tasks : ', res);
result(null, res);
}
});
};
Task.updateById = function(id, task, result){
sql.query("UPDATE tasks SET task = ? WHERE id = ?", [task.task, id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
Task.remove = function(id, result){
sql.query("DELETE FROM tasks WHERE id = ?", [id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
module.exports= Task;

Do not wait for mysql database result in node js

I tried to get result using mysql database query from called function but do not wait for result in called function. Following is my code for users.js file. I got result in getBankDetail function but do not get result in users function.
var db = require("../db/mysqlconnection");
function users(app){
app.get("/users",async function(req, res, next){
let bankDetail = await getBankDetail();
console.log("bankDetail",bankDetail); //Here I do not got result
return res.send(bankDetail);
});
}
async function getBankDetail(){
db.getConnection(async function(err, connection) {
if (err) throw err; // not connected!
await connection.query('SELECT * FROM bank', function (error, results, fields) {
connection.release();
if (error) throw error;
console.log("bank result",results); //Here I got result
return results;
});
});
}
module.exports = users;
My Question is why do not wait for result in called function? I also used async/await functionality.
function getBankDetail(){
return new Promise((resolve, reject) => {
db.getConnection(function(err, connection) {
if (err) reject(err); // not connected!
connection.query('SELECT * FROM bank', function (error, results, fields) {
connection.release();
if (error) reject(err);
console.log("bank result",results); //Here I got result
resolve(results);
});
});
});
}
And then you can use let bankDetail = await getBankDetail();
If you want to use await on your db.getConnection and connection.query you will have to use mysql2/promises library or promisify those functions yourself
Here is the implementation when you use the promisified version of your database driver:
async function getBankDetail(){
const connection = await db.getConnection();
const data = await connection.query('SELECT * FROM bank');
connection.release();
console.log("bank result", data[0]); //Here I got result
return data[0];
}

Node.js, Express and Mysql. How is correct way

What i'am trying to achieve is to make DB query inside closure. Return data and then send stuff to user. I understand that best practice is to use database pooling. Problem is that query is not sync.
Simplified code:
server.js
var express = require('express'),
app = express(),
server = require('http').createServer(app),
mysql = require('mysql');
app.set('DB:pool', mysql.createPool(process.env.DATABASE_URL));
var myClosure = require('./closure.js')(app));
app.get('/somepage', function(req, res) {
var data = myClosure.myquery();
res.send(data);
});
app.get('/anotherpage', function(req, res) {
var data = myClosure.myquery();
res.send(data);
});
app.listen(3000);
closure.js
function myClosure(app) {
var pool = app.get('DB:pool');
return {
myquery: function(inp) {
pool.getConnection(function(err, db) {
if (err) throw err;
db.query('SELECT * FROM table', function(err, rows, fields) {
if (err) throw err;
data = rows[0]
db.release();
});
});
return data;
}
};
}
module.exports = myClosure;
In examples i found all DB related stuff were made in route callback and response was sent in query callback. But way i'm trying to do it is not working as myquery returns undefined because sql query is not done there.
So what is correct way to handle querys ?
Make your query-function handle a callback too:
// server.js
app.get('/somepage', function(req, res) {
myClosure.myquery(function(err, data) {
// TODO: handle error...
res.send(data);
});
});
// closure.js
...
myquery: function(callback) {
pool.getConnection(function(err, db) {
if (err) return callback(err);
db.query('SELECT * FROM table', function(err, rows, fields) {
// release connection before we return anything, otherwise it
// won't be put back into the pool...
db.release();
if (err) return callback(err);
callback(null, rows[0]);
});
});
}
(I left out the inp argument because that didn't seem to be used)