我练习使用MongoDB使用node.js构建Restful API。我有一个发送删除请求router.delete
的路由器。在router.delete
内部,我有两个操作。第一个是根据给定的ID查找并选择productImage
,然后使用fs.unlinkSync
删除物理硬盘中的上载文件。第二个是根据ID删除数据库条目。
如果这样做的话,我会报错,然后删除数据库条目。
TypeError:无法在Product.findById.select.exec.then.docs上读取null的属性“ productImage”
如果我创建两个不同的route.delete
,则可以进行物理删除。如何同时执行两项操作?
这是我的代码:
Router.delete('/:productId', checkAuth, (req, res, next) => {
const id = req.params.productId;
var imageName = "";
Product.findById(id)
.select('productImage')
.exec()
.then(docs => {
imageName = docs.productImage;
fs.unlinkSync(__rootdir + "\\" + imageName);
console.log(doc.productImage);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
Product.deleteOne({_id: id})
.exec()
.then(result => {
res.status(200).json({
message: 'Product Deleted',
request: {
type: 'POST',
url: 'http://localhost:3000/products/',
body: {name: 'String', price: 'Number', productImage: 'String'}
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
答案 0 :(得分:1)
似乎您要查找(并选择一些字段)的文档已被代码的第二部分删除。 (这是可能的,因为所有这些操作都是异步的)。 不确定这是否是最好的解决方案,但是我建议您仅在找到文档并且成功接收到其“ productImage”并启动fs取消链接后才删除它。
Router.delete('/:productId', checkAuth, (req, res, next) => {
const id = req.params.productId;
var imageName = "";
Product.findById(id)
.select('productImage')
.exec()
.then(docs => {
imageName = docs.productImage;
fs.unlinkSync(__rootdir + "\\" + imageName);
console.log(docs.productImage); // by the way you had misspell here
return Product.deleteOne({_id: id}).exec();
})
.then(() => {
res.status(200).json({
message: 'Product Deleted',
request: {
type: 'POST',
url: 'http://localhost:3000/products/',
body: {
name: 'String',
price: 'Number',
productImage: 'String'
}
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
P.S。我也建议您不要使用unlinkSync
方法,因为同步操作会阻塞线程。我宁愿改用fs.unlink
。