Cannot Execute SQL Query in a .map() - javascript

I have an endpoint that receives an array in the req.body. I need to fetch that array and for each element of that array, i need to execute the SQL Update Query. This is the code:
const approveShifts = (req, res) => {
try {
const { guard_id } = req.params;
const { shiftIDs, isBooked } = req.body;
shiftIDs.map((shift_id) => {
connection.query(
`UPDATE shift SET isBooked=${isBooked}, fk_guard=${guard_id} WHERE shiftID=${shift_id}`,
(err, rows) => {
if (!err) {
res.status(200).json({
success: true,
message: `Successfully Approved Shift #${shift_id} for Guard #${guard_id}`,
});
} else {
res.status(404).json({
success: false,
message: "Shift Not Found!",
});
}
}
);
});
} catch (error) {
res.status(500).json({
success: false,
message: error.message,
});
}
};
This is my req.body:
{
"shiftIDs": [64],
"isBooked": 1
}
The issue is, no matter what kind of testing i do, the only output i get is "Shift Not Found!" from the else statement of the query. Nothing else happens. I can't get it to work. Can someone guide me ?

A couple of things here- firstly I recommend you use prepared statements instead of string templates for your query:
// (assuming this is mysql client?)
connection.query('UPDATE shift SET isBooked = ?, fk_guard = ? WHERE shiftID = ?', [isBooked, guard_id, shift_id], (err, rows, fields) => {...})
// if it's the mysql2 client, use connection.execute() instead of connection.query()
This works by replacing each ? with the value in the array, in order. This will help avoid SQL injection problems.
Secondly, you can do this in 1 query instead of mapping by using the IN SQL operator because you are setting the same value for isBooked and fk_guard for every shiftID:
// assuming shiftIDs is an array
connection.query('UPDATE shift SET isBooked = ?, fk_guard = ? WHERE shiftID IN (?)', [isBooked, guard_id, shiftIDs], (err, rows, fields) => {...});
And as someone else said, you should console.log(err) right before res.status(404) to see what the error is. And by the way, if the shift doesn't exist, no rows will be updated but no error will be thrown either, so your response wouldn't be 404.

Related

Avoid getting an array of id in results (mssql - node.js)

I recently started to work with mssql (SQLServer) instead of mySQL.
So I updated my routes to work with mssql.
However I encountered a problem :
When I use a join for example, with 2 tables that have a column 'Id', I got an array of Id instead of a single Id. (both ids are the same)
Is that possible to get only a single id, and not an array ?
Thank you in advance !
const query = 'SELECT sessions.*, chiffres.*, participants.*\
FROM dbo.sessions\
INNER JOIN dbo.participants ON participants.id = sessions.id\
INNER JOIN dbo.chiffres ON chiffres.id = participants.id'
return ps.prepare(query, err => {
if (err) {
return res.json({ errors: { sql: err } })
}
return ps.execute(optsValues, (err, results) => {
if (err) {
return res.json({ errors: { sql: err } })
}
return ps.unprepare(err => {
if (err) {
return res.json({ errors: { sql: err } })
}
return res.json({ sessions: results?.recordset })
})
})
})
results.recordset =>
[
{
"id": [2, 2, 2],
"num_session": "blabla"
...
}
]
I'm not familiar so much with javascript, but as the COLUMN is exactly the same name in each table and you have not aliased the columns then how do you expect the client to separate them out?
It is generally poor practice to use table.* in your queries since the table structure may change over time and your code would not immediately error and perhaps cause adverse impacts dopwnstream. Always be specific with the columns you want to choose.
Try something like this for the query:
const query = 'SELECT sessions.id as SessionID, sessions.num_session, chiffres.id as ChiffresID, chiffres.ca, participants.id as ParticipantID, participants.name\
FROM dbo.sessions\
INNER JOIN dbo.participants ON participants.id = sessions.id\
INNER JOIN dbo.chiffres ON chiffres.id = participants.id'

mySql INSERT query doesn't return nothing, even after res.json() in node

I'm recently started with node and I found myself in the middle of a problem.
I'm trying to Insert a product in my table, but for the id of the product i did not set as auto-increment, so for me to save the id i'm doing a "SELECT MAX"; something like:
router.post('/', (req, res) => {
const { product_description, product_sale_price, product_brand }
conn.query('SELECT MAX(id_product) as id_product FROM products', (error, results) => {
if (error) res.json(error);
let id_max = results[0].id_product
id_max = id_max === null ? 1 : id_max + 1;
conn.query(
`INSERT INTO produtos (id_product, product_description, product_sale_price, id_brand) VALUES ('${id_max}', '${product_description}', '${product_sale_price}', '${product_brand}')`,
(error, results) => {
if (error) res.json(error);
res.json({ message: "Everything ok!" })
})`
})
})
But nothing is returned, recording is normally done in the database but nothing returns in the res.json({ message: "Everything ok!" });
What am i doing wrong?
It looks like you are working with a single table. So I would try fixing the typo in the INSERT statement.
`INSERT INTO products (id_product, product_description, product_sale_price, id_brand) VALUES ('${id_max}', '${product_description}', '${product_sale_price}', '${product_brand}')`,

Res value is null in an app.get call done from vue.js front-end to express back-end

I am calling this code from the front-end and confirmed that there is a proper db connection and that the Id value is properly passed, and that there is a corresponding value in the database, but for some reason, res is null. What am I missing?
app.get("/api/walletlogin/user/:userId", (req, res) => {
id = req.params.userId
var query = {_id: id}
db.collection("Users").findOne(query, (err, result) => {
if (result) {
console.log(result.userName)
} else {
console.log('No User')
}
})
Here is the front-end call:
axios.get('/api/walletlogin/user/' + accounts)
.then((response) => {
console.log('Logged in With ' + accounts)
router.push('/account')
})
.catch((errors) => {
console.log('Cannot log in')
})
}).catch((err) => {
console.log(err, 'err!!')
})
You could try to convert your id to an objectID.
var ObjectId = require('mongodb').ObjectId;
var id = ObjectId(req.params.userId);
to search by id, you must use the ObjectID class from the mongodb package. Here is an example invented by me, it does not reflect the real work, but I hope it will become clear on it:
const { ObjectID } = require('mongodb');
const id = '5ee4f69bfa0b960de8aec158'; // in your example is req.params.userId
db.collection('users').findOne({ _id: new ObjectID(id)}, (error, result) => {
if (error) {
throw error;
}
console.log(result);
})
I am adding the details of the issue initially encountered in case someone else would experience it in the future. The value that is passed from the front-end is a cryptocurrency address. For some reason, some of the characters passed were upper-case, while the same address had been stored in the database with these same characters as lower case. Thus, one needs to add code to make sure that the case of the letters found in the respective addresses is ignored.
J

nodejs callback: doesn't detect any errors, just like if there were no error at all

Node js/Javascript doesn't catch the error while querying mysql server
The nodejs server queries the submittedName from form, checks the database along with submittedName. If submittedName matches with the submittedName, renders success. If it doesn't match, it should render notfound.
But indeed, it does not. Instead, it renders success. Even on wrong input.
app.post("/whatisyourname", (req, res) => {
var submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, rs) => {
//handle the error
if (err) {
console.log(err);
//while it should render the "notfound" file,
//it renders "success"
res.render("notfound");
} else {
//if no error, render success
res.render("success", { myR: rs[0] });
}
}
);
I expect to be forwarded to "notfound" in case of wrong input or just any error
And to be forwarded to "success" in case of correct input
The express server or sql connection or callback won't throw any error in this case. You will get an error if something goes wrong while querying the db, i.e Invalid query or connection error etc. In your case the query executes successfully and gives you the result which is an empty array. You need to manually check and return the result. Change your code like:
app.post("/whatisyourname", (req, res) => {
const submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, results) => {
if (err) {
console.log(err);
res.render("notfound");
} else {
if (results && results.length > 0) {
res.render("success", { myR: results[0] });
} else {
res.render("notfound");
}
}
});
});
Hope this helps :)
var submittedName = req.body.details;
var sql = 'SELECT * FROM giftapp WHERE name = ?';
con.query(sql, [submittedName], function (err, result) {
if (err) res.render("notfound"); // if you view is called notfound.ejs remove the space between not and found.
console.log(result);
res.render("success", { myR: result[0] }); // need success.ejs
});

synchronicity javascript error while accessing the database twice in an endpoint using node/express

I have a company that have a job opening, and other users that want to work there have to make orders to that job position. Overy order has an id of the user that make´s it. I want to also show the name of that user when the company wants to see all the orders for a job.
So, what I was doing was just get all the orders with Order.getOrder, and then get name and email from user for every order and add it to what I am going to return.
The error I´m getting is TypeError: Cannot read property 'then' of undefined in the last then
router.get("/orders", verifyToken, (req, res) => {
Order.getOrders(req.userId, (err, rows) => {
for (x in rows) {
console.log(rows[x].id);
User.forge({id: rows[x].id}).fetch({columns:['email','name']}).then(user => {
rows[x].nameTester = user.get('name');
rows[x].emailTester = user.get('email');
});
}
}).then(function(err, rows) {
res.json({orders: rows});
});
});
And this
Order.getOrders = (userData, callback)=>{
if (connection) {
const query = ...sql query...
connection.query(query, [userData], (err, result, fields) => {
if (err) {
throw err;
} else {
callback(null, result);
}
});
}
};

Categories