Update mysql with nodejs - mysql

I have a list of movies here I am trying to change the one with id
I am trying to change it to this
Below is my code
app.put('/movielist/updateMovie',(req,res) =>{
let update = req.body;
mysqlConnection.query("UPDATE movielist SET name = ?,thumnail_path = ?, description = ?, year_released = ?, language_released = ? WHERE idmovielist = ?",
[update.name,update.thumnail_path,update.description,update.year_released,update.language_released,update.idmovielist],
(err,result) => {
if (!err) {
res.send("Movie list is updated");
} else {
console.log(err);
}
});
});

You are probably looking for something like this :
app.put('/movielist/updateMovie/:id',(req,res) =>{
var id = req.params.id
var update = req.body
mysqlConnection.query('UPDATE movielist SET ? WHERE idmovielist = ?', [update, id], function (err, results) {
if (!err) {
res.send("Movie list is updated");
} else {
console.log(err);
}
})
})
In this case you have from your frontend part to pass the id of the movie you want to update and get it in the params.
You could also pass it in the body of your request without adding it to the url

Related

How to update one or more fields ignoring empty fields in NODE MySQL

I use MySQL and NodeJS and my objective is to update a profile row. But no matter what field the user will chose to update, the backend should ignore the empty field and update the chosen field.
exports.update = (req, res, next) => {
const url = req.protocol + '://' + req.get('host');
let NewURL = req.file.path.split('\\')[1]
const image = url + '/images/' + NewURL; // req.file.path
let postID = req.params.id;
let { title, subtitle, content } = req.body;
//? tilte : oldvalue.title}
const sql2 = `Select * from posts where post_ID = ${postID}`;
db.query(sql2, (error, result) =>{
if (error) throw error;
else {
console.log(result);
const sql = `UPDATE posts
SET
post_title = '${title ? title : result.post_title }' ,
post_subtitle = '${subtitle ? subtitle : result.subtitle }' ,
post_content = '${content ? content : result.content}' ,
imagesLink = '${image ? image : result.image }'
WHERE post_ID = '${postID}'
`;
db.query(sql, (error, result) =>{
if (error) throw error;
else {
res.send(result);
}
});
}
})
}
In this function I tried to implement two sql queries and using the ternary operator, replace the old value from the db with the new value.
Still, I get the undefined fields in the DB and the backend request that the image is required to be updated...
Can somebody help? Thanks.

Node mysql cannot get a response on a query

I have a trouble when i pass a function inside my query. When i run my code without the function just work without any problem. With it on postman is stuck on "Sending request"
Example:
save() {
return db.query(
{
sql: "INSERT INTO contenido (titulo, extencion_archivo, fecha_publicacion) VALUES (?, ?, ?)",
values: [this.titulo, this.extension, this.fecha]
}, function(err, res, fields) {
//More code
}
);
}
Following code work without any problem:
save() {
return db.query(
{
sql: "INSERT INTO contenido (titulo, extencion_archivo, fecha_publicacion) VALUES (?, ?, ?)",
values: [this.titulo, this.extension, this.fecha]
}
);
}
How i call save method:
exports.addVideo = (req, res, next) => {
const titulo = req.body.titulo;
const extension = req.file.mimetype.split("/")[1];
const fecha = new Date();
const videoUrl = req.file.filename;
const video = new Videos(null, titulo, extension, fecha, videoUrl);
video.save().then(() => {
res.json('sending')
})
};
You are using .then on function save() which is not promise returning function. I think that may be the reason for you not getting any response for your postman request.
Try running this code :
function save() {
return new Promise((resolve, reject) => {
db.query(
{
sql: "INSERT INTO contenido (titulo, extencion_archivo, fecha_publicacion) VALUES (?, ?, ?)",
values: [this.titulo, this.extension, this.fecha]
}, function (err, res, fields) {
if (err) {
console.log("Error Occurred :", err);
reject();
}
console.log("Successfully Sent :", res);
resolve();
}
);
})
}
and
exports.addVideo = (req, res, next) => {
const titulo = req.body.titulo;
const extension = req.file.mimetype.split("/")[1];
const fecha = new Date();
const videoUrl = req.file.filename;
const video = new Videos(null, titulo, extension, fecha, videoUrl);
video.save().then(() => {
res.json('sending')
}).catch(() =>{
res.json('Error Occurred')
})
};
Please try this if it works well and good else let me know I will try to help you around this.

Update only some attributes of user in MySQL using Nodejs

I have a put route which can be used to update the user. Everything works fine unless the user will only provide only some params instead of all. How I can fix this? Are there some "simple" solutions for this problem? Because if the user only update his email everything else will be inserted empty..
const id: number = req.params.id;
const password: string = req.body.password;
const email: string = req.body.email;
const lastname: string = req.body.lastname;
const firstname: string = req.body.firstname;
const phoneNumber: string = req.body.phoneNumber;
const permissionID: number = req.body.permissionID;
const imageUrl: string = String(imagePath);
const passwordHash = bcrypt.hashSync(password, 10);
const insertData: [string, string, string, string, string, string, number, number] = [email, passwordHash, phoneNumber, firstname, lastname, imageUrl, permissionID, id];
const query = `UPDATE Users SET email = ?, password = ?, phone_number = ?, first_name = ?, last_name = ?, image_url = ?, permission_id = ? WHERE user_id = ?;`;
connection.query(query, insertData, (err: MysqlError | null) => {
if (!err) {
res.status(200);
res.json( { "Message": "Successfull user was updated" } );
} else {
res.status(500);
res.json( { "Database Error ": err.message } );
}
});
Okay I wrote something I hope this post will help someone. First of course it's possible to save the complete user data model in the client and to resend the complete data to the server. But why should I do this? I don't think this is effecient. If the user just want to change his lastname why I should send the whole payload...Anyway this is the way I solve it.
First I define my possible data I will receive if the user will update some attributes.
enum Validate {
password = 'password',
email = 'email',
firstname = 'first_name',
lastname = 'last_name',
phoneNumber = 'phone_number',
permissionID = 'permission_id'
}
So my function will check the received params and will return the insertData and query. As I'm using password hashing it will check as well if the user wants to update his password.
function updateParams(body: {}, options: [Validate], callBack: (insertData: string[], query: string) => void) {
const insertData: string[] = [];
let query = "";
for (const index in options) {
if (!(body[`${options[index]}`] === '' || body[`${options[index]}`] === undefined || body[`${options[index]}`] === null)) {
query += `${options[index]} = ?, `;
// If user will update password hash it
`${options[index]}` === 'password' ? insertData.push(bcrypt.hashSync(body[`${options[index]}`], 10)) : insertData.push(body[`${options[index]}`]);
}
}
callBack(insertData, query.slice(0, -2));
}
For the next step I'm using promises because there are some if/else statements. The user has the possibilities to just update his picture for example.
const updateUser = (req, res, insertData, query) => {
const promise = new Promise((resolve, reject) => {
let endQuery = '';
if (req.file) {
image.uploadImageToStorage(req.file)
.then((imagePath) => {
if (Object.keys(req.body).length === 0) {
endQuery = `UPDATE Users SET image_url = ? WHERE user_id = ?;`;
insertData.push(String(imagePath));
insertData.push(req.params.id);
resolve([endQuery, insertData]);
} else {
endQuery = `UPDATE Users SET ${query}, image_url = ? WHERE user_id = ?;`;
insertData.push(String(imagePath));
insertData.push(req.params.id);
resolve([endQuery, insertData]);
}
}).catch((error) => {
reject(error.message );
});
} else {
endQuery = `UPDATE Users SET ${query} WHERE user_id = ?;`;
insertData.push(req.params.id);
resolve([endQuery, insertData]);
}
});
return promise;
};
Now I can just use my route.
app.put('/api/v1/users/:id', image.multerMiddleware.single('image'), (req, res) => {
if (((Object.keys(req.body).length !== 0) || req.file) && !isNaN(req.params.id)) {
updateParams(req.body, [Validate.password, Validate.email, Validate.lastname, Validate.firstname, Validate.phoneNumber, Validate.permissionID], (insertData, query) => {
updateUser(req, res, insertData, query)
.then((result) => {
connection.query(result[0], result[1], (err: MysqlError | null) => {
if (!err) {
res.status(200);
res.json({ "Message": "Successfull user was updated" });
} else {
res.status(500);
res.json({ "Database Error ": err.message });
}
});
}).catch((error) => {
res.status(500);
res.json({ "Error ": error.message });
});
});
} else {
res.status(400);
res.json({ "Error": "Please provide the correct paramaters" });
}
});
So now
The user can update only some params
The user can update some params and his picture
The user can update only his picture
It work's fine now.
What I do for when someone is editing a user (or other type of data) is that I retrieve the entire data for the user and show it on the editing form. Then when they make the updates, I send all the data up. This way when I do the SQL update, it will re-save the unchanged data as well as the changed data.
Your other option is a series of conditionals which add to the update statement based off what fields are sent in to update.
You either set only those values that were provided, or, if you really insist on updating all columns (why not the PK while you're at it) you qould query them first.

Nodejs-Mysql Query table name as a variable

How can i pass table name as variable. Basically i want to make e function in which i will take table name as a parameter and object insert record in mysql database in using nodejs
My function will be like
exports.insertIntoDb = function(tableName,insertObj) {
connection.query('INSERT INTO administrator SET ?',insertObj, function(error, result, fields) {
if(error){
res.json({
status:false,
message:'There is some problem with query'
})
}
else{
res.json({
status : true,
data : result,
message: 'user registered successfully'
})
}
});
}
But i am wondering that how to pass table name in this query which is parameter taken from function. I am asking about syntax? I am using nodejs-mysql
Try this:
exports.insertIntoDb = function(tableName,insertObj) {
connection.query('INSERT INTO ?? SET ?', [ tableName, insertObj ], ...)
};
Documented here: https://github.com/mysqljs/mysql#preparing-queries
Inside app.js:
app.put('/updateCell', async function(req, res) {
console.log("REST: PUT /updateCell");
let orderInfo = req.body;
let cellValue = orderInfo.cell;
let CustomerName = orderInfo.CustomerName;
let ColumnName = orderInfo.columnName;
connection.query("UPDATE vehicles SET ?? = ? WHERE order_CustomerName = ?", [columnName, cellValue, customerName],
function(err, result) {
if (err) throw err;
});
res.send();
});
example:
//cellValue = "Fluffiest hat of them all";
//customerName = "Jenny Hopkins";
//columnName = "description";
So the SQL query would be the same as:
UPDATE order SET description = "fluffiest hat of them all" WHERE order_CustomerName = "Jenny Hopkins";

Extend variables outside MySQL query function in NodeJS

I tried to run a function which returns a value back but am getting undefined.
function getMessageId(myId, user){
$query = "SELECT * FROM startMessage WHERE (userFrom = '"+myId+"' AND userTo = '"+user+"') OR (userFrom = '"+user+"' AND userTo = '"+ myId+"')";
connect.query($query, function(error, rows){
sql = rows[0];
console.log(sql);
return sql.id;
})
}
// running the function
msgId = getMessageId(userFrom, userTo);
console.log(msgId);
Now when I tried to console.log the sql I get the expected result like
{
id : 3,
userFrom : 3,
userTo : 1,
type : "normal",
date : "2017-06-25 06:56:34",
deleted : 0
}
But when I console.log the msgId I get undefined. I am doing this on NodeJS, please any better solution?
Short answer, Because its an asynchronous operation.
The outer console.log happens before the getMessageId returns.
If using callbacks, You can rewrite getMessageId as
let msgId
function getMessageId(myId, user, callback){
$query = "SELECT * FROM startMessage WHERE (userFrom = '"+myId+"' AND userTo = '"+user+"') OR (userFrom = '"+user+"' AND userTo = '"+ myId+"')";
return connect.query($query, function(error, rows){
sql = rows[0];
console.log(sql);
callback(sql.id);
})
}
function setMsgId(id) {
msgId = id;
}
And then call it as,
getMessageId(userFrom, userTo, setMsgId);
Further I would suggest you look into Promises.
Which would very well streamline the flow.
Using Promises, getMessageId should look something like
function getMessageId(myId, user){
$query = "SELECT * FROM startMessage WHERE (userFrom = '"+myId+"' AND
userTo = '"+user+"') OR (userFrom = '"+user+"' AND userTo = '"+
myId+"')";
const promise = new Promise((resolve, reject) => {
connect.query($query, function(error, rows){
sql = rows[0];
console.log(sql);
resolve(sql.id);
})
return promise.
}
Post this, You can use it as
getMessageId(myId, user).then((msgId) => console.log(msgId))
create a wrapper for mysql use
// service/database/mysql.js
const mysql = require('mysql');
const pool = mysql.createPool({
host : 'host',
user : 'user',
password : 'pass',
database : 'dbname'
});
const query = (sql) => {
return new Promise((resolve, reject) => {
pool.query(sql, function(error, results, fields) {
if (error) {
console.error(error.sqlMessage);
return reject(new Error(error));
}
resolve(results);
});
});
}
module.exports = { query };
then call from another script with async funcion and await
// another file, with express route example
const db = require('/service/database/mysql.js')
module.exports = async (req, res) => { // <-- using async!
let output = []; // <-- your outside variable
const sql = 'SELECT * FROM companies LIMIT 10';
await db.query(sql) // <-- using await!
.then(function(result) {
output = result; // <-- push or set outside variable value
})
.catch(e => {
console.log(e);
});
// await db.query("next query" ...
// await db.query("next query" ...
// await db.query("next query" ...
res.json(output);
}
This is probably NOT a proper way, and a hack, but sharing for information purpose (you may not like to use this)
Simply use an if else and call the function once inside the query (if true), and call it outside (if false)
if (id != null) {
// Get Details
const query = pool.execute('SELECT * FROM `sometable` WHERE `id` = ?', [id], function(err, row) {
if (err) {
console.log(err)
return
} else {
if (row && row.length) {
// Do Something
}
}
})
} else {
// Do Something
}