Access to parent records in nested MySQL Queries - javascript

I have a problem with MySQL nested queries. First i want get all products, then in a nested query, iterate over all products (each product is a JSON) and for each product get their images adding a key 'images' to the current product.
exports.findAll = function(callback) {
var Database = require('../config/database.js')
var DBConnection = new Database()
var connection = DBConnection.connect()
connection.query('SELECT * FROM product', function(err, records, fields) {
var products = records
for(var i=0; i<products.length; i++) {
connection.query('SELECT Image FROM product_images WHERE Product = ?', [products[i].Id],
function(err, images, fields) {
console.log(products[i])
})
}
DBConnection.disconnect()
callback(err, products)
})
}
In the nested query, products[i] is undefined and can't add the images. ¿How can i solve this?
If a first get the records in the route, and then get the images calling to another function passing the records getted and iterate over they, maybe works, but i wanna know if exists a more 'easy' way.
Thanks.

Solved iterating only with for each:
exports.findAll = function(callback) {
var Database = require('../config/database.js')
var DBConnection = new Database()
var connection = DBConnection.connect()
var query = 'SELECT * FROM product'
connection.query(query, function(err, products) {
products.forEach(function(cur) {
var query = 'SELECT Image FROM product_images WHERE Product = ?'
connection.query(query, [cur['Id']], function(err, images) {
cur['images'] = images
callback(err, products)
})
})
DBConnection.disconnect()
})
}
Can someone explain me why works with forEach and don't with normal for or for in?

Related

Couldn`t display callback buttons (Telegraf lib.) using forEach method

My task is to add callback buttons for each element of array which i get from MySql table.
let select = `SELECT Bike_num FROM rent.Bike_Status_num where Last_Station = 1 and B_Status = 'OK';`
con.query(select, function (err, result) {
if (err) {
console.log(err);
return err;
} else {
let replyButtons = [];
let bikes_free = result;
ctx.reply('Chose bicycle',
Markup.inlineKeyboard([
[Markup.button.callback(`${bikes_free[0].Bike_num}`, `${bikes_free[0].Bike_num}`),
Markup.button.callback(`${bikes_free[1].Bike_num}`, `${bikes_free[1].Bike_num}`),
Markup.button.callback(`${bikes_free[2].Bike_num}`, `${bikes_free[2].Bike_num}`),
Markup.button.callback(`${bikes_free[3].Bike_num}`, `${bikes_free[3].Bike_num}`)],
[Markup.button.callback(`${bikes_free[4].Bike_num}`, `${bikes_free[4].Bike_num}`),
Markup.button.callback(`${bikes_free[5].Bike_num}`, `${bikes_free[5].Bike_num}`),
Markup.button.callback(`${bikes_free[6].Bike_num}`, `${bikes_free[6].Bike_num}`),
Markup.button.callback(`${bikes_free[7].Bike_num}`, `${bikes_free[7].Bike_num}`)]
]))
I don`t know how to display this buttons using forEach method or any other convenient method.
Tried 2 ways, but got an errors.

promise logic with sql in nodejs when making calls to database

I have the code below that is reliant on two api calls to two different tables. It first gets data from database, gets an id from there, makes another call to another table, gets data from there and appends it to each value from the first call. The code works fine in theory but I just need to be able to resolve the final product by creating a chain of events. The final resolve should wait for the entire code to finish executing and then return the value of first_call.
Here is my code. Let me know how I can modify it.
Updated code
function getUsers() {
return new Promise((resolve, reject) => {
var sql = `SELECT p.customer, p.fname, p.lname, p.email, p.user, c.name AS organizationName, c.email AS organizationEmail c.did AS phoneNumber FROM people AS p LEFT JOIN customers AS c ON c.id = p.customer`;
console.log(sql)
con.query(sql, function (err, result) {
if (err) throw err; 
resolve(result); 
});
});
}
Old code
function getUsers() {
return new Promise((resolve, reject) => {
var first_call = []
var sql = `SELECT customer, fname, lname, email, user FROM people`;
con.query(sql, function (err, result) {
if (err) throw err;
first_call = result
});
for (let i = 0; i < first_call.length; i++) {
var sql2 = `SELECT name, email, did FROM customers WHERE id = ${first_call[i].customer}`;
con.query(sql2, function (err, result2) {
first_call[i].organizationName = result2[0].name;
first_call[i].organizationEmail = result2[0].email;
first_call[i].phoneNumber = result2[0].did;
});
}
resolve(first_call);
});
}
The simplest solution would be to combine the two queries with a JOIN:
SELECT p.customer, p.fname, p.lname, p.email, p.user, c.name AS organizationName, c.email AS organizationEmail, c.did AS phoneNumber
FROM people AS p
LEFT JOIN customers AS c ON c.id = p.customer
But if you really want two queries, here's how to rewrite your promise code using async and await.
You should also use a parameter in the SQL rather than substituting a variable.
async function getUsers() {
var first_call = []
var sql = `SELECT customer, fname, lname, email, user FROM people`;
first_call = await con.query(sql)
var sql2 = `SELECT name, email, did FROM customers WHERE id = ?`;
for (let i = 0; i < first_call.length; i++) {
let result2 = await con.query(sql2, [first_call[i].customer]);
first_call[i].organizationName = result2[0].name;
first_call[i].organizationEmail = result2[0].email;
first_call[i].phoneNumber = result2[0].did;
}
return first_call;
}

Express passing arrays into sql (express/mssql/react)

I am trying to upload two arrays into my sql database.
This is what I have come up with.(this is my server.js using a endpoint from my client side)
My express
app.post("/post-question-answers", async (req, res) => {
console.log("!called");
try {
await sql.connect(config);
// create Request object
var request = new sql.Request();
let results = req.body.results;
let questions = [];
let answers = [];
results.forEach(element => questions.push(element.question));
results.forEach(element => answers.push(element.answer));
for (var i = -1; i < results.length; i++) {
request.input("Question", sql.VarChar, questions[i]);
request.input("Answer", sql.VarChar, answers[i]);
request.execute("dbo.AddQuestionResponses", function(err, recordset) {
if (err) console.log(err);
// send records as a response
res.json(recordset);
});
}
} catch (e) {
console.log(e);
}
});
My sql stored procedrue
alter procedure AddQuestionResponses
#Question nvarchar (50),
#Answer nvarchar (50)
as
insert into QuestionResponses(QuestionWhenAnswered, QuestionResponse)
values (#Question ,#Answer )
However this throws
RequestError: The parameter name Question has already been declared. Parameter names must be unique
I believe this is because
request.input("Question", sql.VarChar, questions[i]);
request.input("Answer", sql.VarChar, answers[i]);
need to be unique and as they are in a for loop they are repeated within the statement. Is there a way in which I can make this a valid transaction with the database and so that these are unique.
Thankyou for your time :)
I solved this issue by putting
var request = new sql.Request();
within the for loop.

javascript- pushing resultset from database to array failed

I'm running a query to fetch the list of new users. Query is correct. It returns 15 users. I push the resultset into a javascript array but only the last record from the resultset is getting saved.
Here's my code:
var query = `SELECT *
FROM users
WHERE (status ='New')`;
var query = connection.query(query),
response = []; // this array will contain the result of our db query
query
.on('error', function (err) {
console.log(err);
})
.on('result', function (res) {
// it fills our array looping on each user row inside the db
response.push(res);
/*
for (var key in res) {
if (res.hasOwnProperty(key)) response.push(res[key]);
}
*/
})
.on('end', function () {
console.log('console')
});
As you can see response.push(res); is the line of code where I do this. Below that I have comment a few lines. I tried that option to push each row from the resultset but it ain't giving any results.
try a for loop
for(var i in res){
response.push(res[i]);
}
I maybe underestimate your test but you maybe check result at the wrong place.
You should do it on the 'end' callback.
.on('end', function () {
console.dir(res)
});

NodeJS - how can get mysql result with executed query?

I am new in NodeJS with mysql (npm install mysql).
When I try to execute query like
connection.query("select ?? from users where id = ?",[["id","fname","lname"],req.body.userid],function (err, rows) {
**here I want query which above executed**
});
I want query in callback function which executed.
How can I get it??.
var c = connection.query("select ?? from users where id = ?",[["id","fname","lname"],req.body.userid],function (err, rows) {
console.log(c.sql)
});
connection.query("select ?? from users where id = ?",[["id","fname","lname"],req.body.userid],function (err, rows) {
res.send(rows);
});
also in preference swith the string query to :
"select id,fname,lname from users where id = '"+req.body.userid+"'"

Categories

Resources