Function: Select MySQL and Return JSON - javascript

Please help me, I need to implement a function in a separate module file and in the route where the render has to call this function receiving the query data:
function getSobre() {
return new Promise((resolve, reject) => {
db.query(`SELECT * FROM sobre ORDER BY cod DESC LIMIT 1`, (err, results) => {
if (err) {
return reject(err);
} else {
return resolve(results);
}
});
});
}
const data = {
title: getSobre().then(data => {
/*
* HERE How do I return this "data" to the "title:" ?????????????
*/
}),
name: 'Fabio',
profession: 'Analista'
}
module.exports = data;

db.query is a Js callback . Which will wait for the result , then return anything.
So data will always be empty since it is getting returned much before db.query getting full resolved
You should wrap this in a native promise, and then resolve the promise :
function getTabela{
return new Promise(function(resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let sql = "SELECT * FROM sobre ORDER BY cod DESC LIMIT 1";
var data = {};
db.query(sql, (err, results, fields) => {
if (results.length > 0) {
resolve(fields)
} else {
console.log('Erro: ' + err);
}
});
});
}
getTabela().then(function(rows) {
// now you have your rows, you can see if there are <20 of them
}).catch((err) => setImmediate(() => { throw err; }));
This way you should always have the data which is expected out of the query.

Related

Node/ MySql not working when I try to INSERT data into a newly create column to the database

I am working on my first MySQL/ Nodejs project. I have the following lines of code that are working correctly.
async insertNewBrand(brand) {
try {
const dateAdded = new Date();
const insertId = await new Promise((resolve, reject) => {
const query = "INSERT INTO wines (brand, date_added) VALUES (?,?);";
connection.query(query, [brand, dateAdded] , (err, result) => {
if (err) reject(new Error(err.message));
resolve(result.insertId);
})
});
return {
id : insertId,
brand : brand,
dateAdded : dateAdded
};
} catch (error) {
console.log(error);
}
}
When I try to include a new parameter, the code breaks (new code below). Here I am trying to add varietal but adding that in all the needed locations seems to break the code.
async insertNewBrand(brand,varietal) {
try {
const dateAdded = new Date();
const insertId = await new Promise((resolve, reject) => {
const query = "INSERT INTO wines (brand, varietal, date_added) VALUES (?,?,?);";
connection.query(query, [brand, varietal, dateAdded] , (err, result) => {
if (err) reject(new Error(err.message));
resolve(result.insertId);
})
});
return {
id : insertId,
brand : brand,
dateAdded : dateAdded
};
} catch (error) {
console.log(error);
}
}
I am getting the error "Cannot read properties of undefined (reading 'insertId')". I am not sure what I am doing wrong. Any ideas?
There must be an error in the SQL, which is being reported by reject(err.message). When there's an error, you shouldn't try to use the result object. So use else so you either reject or resolve, but not both.
connection.query(query, [brand, varietal, dateAdded] , (err, result) => {
if (err) {
reject(new Error(err.message));
} else {
resolve(result.insertId);
}
})

Getting Data from Azure SQL database in Azure Function

I'm having problems getting data from my AZURE SQL database. My code does get data, but not all of it. The intention is that the function needs to take all users in wicht the age is X (f.ex.:20)and return an array with those users. Right now the code just return the first user it finds on the database. I am using Azure-functions in which I use Insomnia to test the result.
Here is the function that gets the data from the DB:
function testfunc(age){
return new Promise ((resolve, reject) =>{
let result = [];
const sql = 'SELECT * FROM [datingschema].[user] where age = #age'
const request = new Request(sql, function(err){
if (err){
console.log("beforeerr");
console.log(err) //ingen err - så det godt nok!
console.log("aftererr");
reject(err);
}
})
request.addParameter('age', TYPES.Int, age)
request.on('row', (columns) => {
columns.forEach(column =>{
result.push(column.value)
})
resolve(result)
});
connection.execSql(request)
})
}
Here is a part of my code in Azure-function where I call for the function. There should be no errors in there as it works fine when I need to get only one user:
const db = require('../database/db');
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.')
try {
await db.startDb(); //start db connection
} catch (error) {
console.log("Error connecting to the database", error.message)
}
switch (req.method) {
case 'GET':
await get(context, req);
break;
case 'POST':
await post(context, req);
break
default:
context.res = {
body: "Please get or post"
};
break
}
}
async function get(context, req){
try{
let id = req.query.age
let user = await db.testfunc(id)
context.res = {
body: user
};
} catch(error){
context.res = {
status: 400,
body: `No User - ${error.message}`
}
}
}
The error happens, because you resolve your promise after you have read the first row. Consider the following:
function testfunc(age){
return new Promise ((resolve, reject) =>{
let result = [];
const sql = 'SELECT * FROM [datingschema].[user] where age = #age'
const request = new Request(sql, function(err){
if (err){
console.log("beforeerr");
console.log(err) //ingen err - så det godt nok!
console.log("aftererr");
reject(err);
}
})
request.addParameter('age', TYPES.Int, age)
// This is executed multiple times, once for each row
request.on('row', (columns) => {
let row = []
// Accumulate the columns to a row
columns.forEach(column =>{
row.push(column.value)
})
// Don't resolve here. Instead append to result..
// resolve(result)
result.push(row)
});
// This is executed once, when the query has completed
request.on('done', () => {
// .. and resolve here
resolve(result)
})
connection.execSql(request)
})
}

Should i use promise or callback in the following code?

I have some routes
routes.js
var express = require("express");
var router = express.Router();
const { controllerMethod1, controllerMethod2 } = require("./controller");
router.get("/route1", controllerMethod1);
router.get("/route2", controllerMethod2);
module.exports = router;
if i use promise variable as global,
its used by all method in controller.js.
should i use global or local variable for promise ?
controller.js
const {
serviceMethod1,
serviceMethod2,
serviceMethod1ByDate,
} = require("./services");
let promise; //global promise variable
const controllerMethod1 = (req, res) => {
//let promise; local promise variable
//This is for Callback
if (req.query.date) {
serviceMethod1ByDate(req.query.date, (err, result) => {
if (err) {
res.status(500).json({
status: "error",
message: "error using callback",
});
}
if (result) {
res.status(200).json({
status: "success",
message: "success using callback",
});
}
});
} else {
serviceMethod1((err, result) => {
if (err) {
res.status(500).json({
status: "error",
message: "error using callback",
});
}
if (result) {
res.status(200).json({
status: "success",
message: "success using callback",
});
}
});
}
// This is for Promise
promise = req.query.date
? serviceMethod1ByDate(req.query.date)
: serviceMethod1();
Should i use way 1 or way 2 ?
if multiple users request one or more routes at the same time,can handleResponse method work correctly?
Way 1 for promise
promise
.then((results) => {
return res.json({
status: "success with promise variable",
data: results,
});
})
.catch((error) => {
return res.status(500).json({
status: "error with promise variable",
message: "there is no person details",
});
});
Way 2 for Promise
handleResponse(promise, res);
//this method is working for all routes when i use promise
const handleResponse = (results, response) => {
results
.then((result) => {
return response.json({
status: "success with promise variable in handleResponse",
data: result,
});
})
.catch((error) => {
return response.status(500).json({
status: "error with promise variable handleResponse",
message: "Internal Server Error",
});
});
};
controller.js
const controllerMethod2 = (req, res) => {
//------------------ Using Callback Method -------------
serviceMethod2((err, result) => {
if (err) {
res.status(500).json({
status: "error",
message: "error using callback",
});
}
if (result) {
res.status(200).json({
status: "success",
message: "success using callback",
});
}
});
//------------------ Using Promise Method -------------
//local variable
let promise;
promise = serviceMethod2();
//Way 1 for Promise
promise
.then((result) => {
//...
})
.catch((err) => {
//...
});
//Way 2 for Promise
handleResponse(promise, res);
};
module.exports = { controllerMethod1, controllerMethod2 };
service.js
const pool = require("../../../config/database");
//-----------------------Using Callback Mehthod----------------
const serviceMethod1 = async (CallBack) => {
let query = "select * from databse";
await pool.query(query, [], (error, results, fields) => {
if (error) {
return CallBack(error);
}
return CallBack(null, results);
});
};
const serviceMethod1ByDate = async (date) => {
let query = "select * from databse where date ?";
return await new Promise((resolve, reject) => {
pool.query(query, [date], (error, results, fields) => {
if (error) {
return CallBack(error);
}
return CallBack(null, results);
});
});
};
const serviceMethod2 = async (Callback) => {
let query = "select * from database";
await pool.query(query, [], (error, results, fields) => {
if (error) {
return CallBack(error);
}
return CallBack(null, results);
});
};
//-----------------------Using Promise Method----------------
const serviceMethod1 = async () => {
let query = "select * from databse";
return await new Promise((resolve, reject) => {
pool.query(query, [], (error, results, fields) => {
if (results) {
resolve(results);
} else {
reject(error);
}
});
});
};
const serviceMethod1ByDate = async (date) => {
let query = "select * from databse where date ?";
return await new Promise((resolve, reject) => {
pool.query(query, [date], (error, results, fields) => {
if (results) {
resolve(results);
} else {
reject(error);
}
});
});
};
const serviceMethod2 = async () => {
let query = "select * from database";
return await new Promise((resolve, reject) => {
pool.query(query, [], (error, results, fields) => {
if (results) {
resolve(results);
} else {
reject(error);
}
});
});
};
module.exports = {
serviceMethod1,
serviceMethod1ByDate,
serviceMethod2,
};
if i use promise variable as global, its used by all method in controller.js. should i use global or local variable for promise ?
You should use local variable for this type of operation as global variable are generally used to define constants or methods. They cannot be used as temporary values because it's value can be changed anytime and that'll result in conflict with other functionalities and so must be avoided.
Should i use way 1 or way 2 ? if multiple users request one or more routes at the same time,can handleResponse method work correctly?
Way 2 is more efficient that Way 1 because if you use way 1 then you will have to do it for every method in the controller. Way 2 is like a common method where you can format your response and most of the developers use it.
It doesn't make any difference whether you use callbacks or promises but just a clean way to do things.
Instead of using this:
const serviceMethod1 = async () => {
let query = "select * from databse";
return await new Promise((resolve, reject) => {
pool.query(query, [], (error, results, fields) => {
if (results) {
resolve(results);
} else {
reject(error);
}
});
});
};
Use this:
// Remove the async await from here and handle the response/error where the below method is called by putting it in try catch block.
const serviceMethod1 = () => {
let query = "select * from databse";
return new Promise((resolve, reject) => {
pool.query(query, [], (error, results, fields) => {
if (results) {
resolve(results);
} else {
reject(error);
}
});
});
};
// otherFile.js
someMethod = async () => {
try {
const result = await serviceMethod1();
// handle the response
} catch {
// handle the error
}
}

Javascript, error when return on a main function

I have my function who call the DB to do something :
function callQuery(query) {
db.query(query, (err, res) => {
if (err) {
// Error DB connecion
console.log(err.stack)
} else {
// Send back the results
return(res.rows[0])
}
})
}
My problem is when I call this function by :
const idUser = callQuery("INSERT INTO blablabla RETURNING *")
My data is successfully added in the DB, but idUser came null. It should be res.rows[0]
I am using this tutorial (who instead of setting a variable, call console.log) : https://node-postgres.com/features/connecting
Thank you in advance
I think this is something due to asynchronous
let promisess = new Promise(function(resolve, reject) {
function callQuery(query) {
db.query(query, (err, res) => {
if (err) {
// Error DB connecion
console.log(err.stack)
} else {
// Send back the results
resolve(res.rows[0])
}
})
}
});
promisess.then((res)=> {
your data in res
});

Results from SQL Query not getting passed to resolve() in Node Js Promise

So I thought I was doing this right, but I guess not. I am trying to pass the results from the query to the function in then(). I have a console.log() logging results from inside the two functions. The first one spits out the results as it should. The second one is giving me undefined and I can't figure out what I'm doing wrong.
var dbConnect = () => new Promise(
(res, rej) => {
var connection = mysql.createPool(Config.mariaDBCred);
connection.getConnection((err, connection) => {
if(err) return rej(err);
return res(connection);
});
}
);
var dbQuery = (connection, queryString, paramArray) => new Promise(
(res, rej) => {
var sql = mysql.format(queryString, paramArray);
connection.query(sql,
(err, results, fields) => {
connection.release();
console.log(results); //THIS DISPLAYS RESULTS FROM THE QUERY CORRECTLY
if(err) return rej(err);
return res(results, fields);
}
);
}
);
//CHECK IF EMAIL EXISTS
module.exports.doesEmailExist = (email, callback) => {
dbConnect().then(
(connection) => {
dbQuery(
connection,
'SELECT `id`, `password_hash` FROM `users` WHERE email = ?',
[email]
)
}
).then(
(results, fields) => {
console.log(results); //THIS DISPLAY UNDEFINED
if(results.length > 0) return callback(true, results);
return callback(false, "Email does not exist.");
}
).catch(
(reason) => {
console.log(reason);
return callback(false, "Internal Error");
}
);
}
I'm not sure if the edits below will resolve all of your issues, but in terms of your problems with regards to the Promise API, they should steer you in the right direction.
First, in the dbQuery function, I resolve an object because you can only resolve a single value in a promise.
Second, to chain promises, you must return promises. In your first then handler you weren't returning the Promise from dbQuery (after dbConnect).
Finally, I changed your second then handler to work with the single resolved object, rather than the multiple parameters used previously. Before, had everything worked, results would have been defined, but not fields. It's good practice to resolve an Array or an Object in cases like these. If your using es6, object/array destructuring makes ease of this.
Another note. If you are using Promises, consider ditching the callback pattern implemented in your doesEmailExist function, if not altogether. It's more consistent, and you won't have to wrap catch handlers, unless targeting specific error cases. Food for thought.
var dbConnect = () => new Promise(
(res, rej) => {
var connection = mysql.createPool(Config.mariaDBCred);
connection.getConnection((err, connection) => {
if(err) return rej(err);
return res(connection);
});
}
);
var dbQuery = (connection, queryString, paramArray) => new Promise(
(res, rej) => {
var sql = mysql.format(queryString, paramArray);
connection.query(sql,
(err, results, fields) => {
connection.release();
console.log(results); //THIS DISPLAYS RESULTS FROM THE QUERY CORRECTLY
if(err) return rej(err);
// return res(results, fields); NOPE, can only resolve one argu
return res({ results: results, fields: fields }) // resolve an object
}
);
}
);
//CHECK IF EMAIL EXISTS
module.exports.doesEmailExist = (email, callback) => {
dbConnect().then(
(connection) => {
// Return the promise from `dbQuery` call
return dbQuery(
connection,
'SELECT `id`, `password_hash` FROM `users` WHERE email = ?',
[email]
)
}
).then(
(response) => {
// Can only resolve one argument
var results = response.results;
var fields = response.fields;
console.log(results); //THIS DISPLAY UNDEFINED
if(results.length > 0) return callback(true, results);
return callback(false, "Email does not exist.");
}
).catch(
(reason) => {
console.log(reason);
return callback(false, "Internal Error");
}
);
}

Categories

Resources