MySQL NodeJS .then() s not a function - mysql

Can't I use promise for nodeJS mysql query?
// My DB settings
const db = require('../util/database');
db.query(sqlQuery, [param1, param2])
.then(result => {
console.log(result);
})
.catch(err => {
throw err;
});
It is returning: TypeError: db.query(...).then is not a function

You mentioned in the comments that you want logic after the query block to be awaited, without placing that logic inside of the callback. By wrapping the method with a Promise, you can do that as such:
try {
const result = await new Promise((resolve, reject) => {
db.query(sqlQuery, (error, results, fields) => {
if (error) return reject(error);
return resolve(results);
});
});
//do stuff with result
} catch (err) {
//query threw an error
}

Something like this should work
function runQuery(sqlQuery){
return new Promise(function (resolve, reject) {
db.query(sqlQuery, function(error, results, fields) {
if (error) reject(error);
else resolve(results);
});
});
}
// test
runQuery(sqlQuery)
.then(function(results) {
console.log(results)
})
.catch(function(error) {
throw error;
});

mysql package does not support promise. We can use then only a function call returns a promise.You can use mysql2 which has inbuilt support for Promise. It will also make your code more readable. From mysql2 docs:
async function main() {
// get the client
const mysql = require('mysql2/promise');
// create the connection
const connection = await mysql.createConnection({host:'localhost',
user: 'root', database: 'test'});
// query database
const [rows, fields] = await connection.execute(query);
// rows hold the result
}
I would aslo recommend you to learn about callbacks, promise and async-await

Related

Return mysql query result using Promise

I'm currently a little confused as to how to properly wait for the promise to finish before returning the result from a query
Here is my current code:
const getLeaderboardValues = async () => {
const SQLConnection = await getSQLConnection();
return new Promise((resolve, reject) => {
SQLConnection.query(getValuesSQLQuery, (err, result) => {
if (err) { reject(err) }
return resolve(result);
});
SQLConnection.end()
})
}
const runtime = () => {
getLeaderboardValues().then((result) => {
console.log(result);
})
}
The code above does log the correct results while debbugging, i believe this is because i'm giving the code more time to render with the breakpoints, however when running normally i get undefined
I believe the SQLConnection.end() line is executing before the query is returned, given it is outside the query statement.
The below may solve your issue, however I do not recommend opening a connection and closing it on every request in production systems.
const getLeaderboardValues = async () => {
const SQLConnection = await getSQLConnection();
return new Promise((resolve, reject) => {
SQLConnection.query(getValuesSQLQuery, (err, result) => {
if (err) {
reject(err)
return SQLConnection.end()
}
SQLConnection.end()
return resolve(result);
});
})
}
const runtime = () => {
getLeaderboardValues().then((result) => {
console.log(result);
})
}

Returning undefined from mySQL

I know the database is connecting with the code as, when i console.log(res) with the code below it is returning the correct data,
const orm={
selectAll(){
connection.query('SELECT * FROM burgers', (err,res) => {
if (err) throw err;
console.log(res)
return res;
});
},
Yet when i console.log(burgers) from this function in the code below it is returning an undefined
app.get(`/`, function (req, res) {
const burgers = orm.selectAll();
console.log(burgers)
res.render(`index`, burgers);
});
I understand this may be a very simple answer but i personally just cannot work it out any help is welcomed.
selectAll is using a callback style method inside it. You can not get the response syncronously. You need to either pass the callback to selectAll or change it to use promise like this
function selectAll() {
return new Promise((reoslve, reject) => {
connection.query("SELECT * FROM burgers", (err, res) => {
if (err) {
reject(err);
}
reoslve(res);
});
});
}
You can then use it like this
app.get(`/`, function async (req, res) {
const burgers = await selectAll();
console.log(burgers)
res.render(`index`, burgers);
});
Your selectAll method will not return any value.
query get an lambda callback function as second parameter AND query is asyncron
One way is to return an Promise from selectAll
const orm = {
selectAll(callback) {
return new Promise((resolve, reject) => {
connection.query('SELECT * FROM burgers', (err, res) => {
if (err) {
reject(err);
} else {
resolve(res)
}
})
})
},
Than you can get your result:
app.get(`/`, function (req, res) {
orm.selectAll().then( burgers => {
console.log(burgers)
res.render(`index`, burgers);
});
});

Nodejs async/await for MySQL queries

I trying to execute 2 MySQL queries sequentially in Node.JS. MySQL queries work properly by itself.
I would like to do it with async/await function to be sure record is inserted before it's updated.
Here is the code:
router.post('/assign_new_item_id', async (req, res) => {
.....
try {
let qr1= "INSERT INTO foo1 ........;"
await pool.query( qr1, (err) => {
if (err) throw err;
});
let qr2= "UPDATE foo1 .....;"
await pool.query( qr2, (err) => {
if (err) throw err;
});
}catch(err){
console.log(err)
}
It seems that execution "hangs" within first await await block. What is the best way the ensure that both queries are executed consequently.
Thanks in advance for any help.
To await you need a Promise, Not Callback. In your case you are not returning a promise to await.
router.post('/assign_new_item_id', async (req, res) => {
// .....
try {
let qr1 = "INSERT INTO foo1 ........;"
await new Promise((res, rej) => {
pool.query(qr1, (err, row) => {
if (err) return rej(err);
res(row);
});
});
let qr2 = "UPDATE foo1 .....;"
await new Promise((res, rej) => {
pool.query(qr2, (err, row) => {
if (err) return rej(err);
res(row);
});
});
} catch (err) {
console.log(err)
}
});
Here I am promisifing the pool.query method and returning a promise.

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];
}

NodeJS and SQL with Async

I'm trying to use a SQL query with NodeJs but the async part really mess me up. When i print the return it gets "undefined". How can i sync this?
function SQL_test(blos) {
DB.query("Select profesor_id from materiador where materia_id = '"+blos+"';",function (err, results, fields) {
return results;
});
}
console.log(SQL_test(1));
Thanks!
So your answer is currently a promise. You'll have to read about Async and Await to do more synchronous JS.
Most of the JS for NodeJS is currently async. Below is a rewritten version of your example properly utilizing the callback method for your DB.
function callback (err, results, fields) {
if (err) {
console.log(err);
return err;
}
console.log(results, fields);
return results;
};
function SQL_test(blos) {
DB
.query("Select profesor_id from materiador where materia_id = '"+blos+"';", callback);
}
SQL_test(1);
To do the same thing synchronously you have to still have an outer level promise, otherwise Async and Await won't work how you want it to. There's no true synchronous way to handle this is javascript because it executes without waiting for the response.
function sqlTest(blos) {
return new Promise((resolve, reject) => {
DB.query(
`Select profesor_id from materiador where materia_id = '${blos}';`,
(err, results) => {
if (err) return reject(err)
resolve(results)
}
);
}
)
sqlTest(1)
.then(console.log)
.catch(console.error)