我有一个可用于更新用户的放置路线。一切正常,除非用户只提供一些参数而不是全部。我怎么解决这个问题?这个问题有一些“简单”的解决方案吗?因为如果用户只更新他的电子邮件,其他所有内容都将被插入空..
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 } );
}
});
答案 0 :(得分:0)
当有人编辑用户(或其他类型的数据)时,我所做的是我为用户检索整个数据并在编辑表单上显示。然后当他们进行更新时,我会发送所有数据。这样,当我进行SQL更新时,它将重新保存未更改的数据以及更改的数据。
您的另一个选项是一系列条件,它们根据发送的更新字段添加到更新语句中。
答案 1 :(得分:0)
你要么只设置那些提供的值,要么,如果你真的坚持要更新所有列(为什么不是PK,而你还是它),你可以先查询它们。
答案 2 :(得分:0)
好的,我写了一些内容,希望这篇文章可以帮助别人。首先,当然可以将完整的用户数据模型保存在客户端中,并将完整的数据重新发送到服务器。但我为什么要这样做呢?我不认为这是有效的。如果用户只是想改变他的lastname
为什么我应该发送整个有效载荷...无论如何,这就是我解决它的方式。
首先,如果用户更新某些属性,我将定义我将收到的可能数据。
enum Validate {
password = 'password',
email = 'email',
firstname = 'first_name',
lastname = 'last_name',
phoneNumber = 'phone_number',
permissionID = 'permission_id'
}
所以我的函数将检查收到的参数并返回insertData和查询。当我使用密码哈希时,如果用户想要更新密码,它也会检查。
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));
}
下一步我使用promises,因为有一些if / else语句。例如,用户可以更新他的图片。
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;
};
现在我可以使用我的路线。
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" });
}
});
所以现在
现在工作正常。