我正在NodeJS和Express中创建一个CRUD应用程序,以自学后端编程。在数据库方面,我使用mongodb。 这个项目基本上是一种商店后台(目前没有前端),您可以在其中添加,更新删除或查看ITEM。 (要提及,使用POSTMAN作为请求处理程序。)
问题描述:该更新方法当前有效,因此我可以根据其ID更新ITEM,但是如果我错过了一个字段,那么为此字段指定的值为'null',这是合乎逻辑的。 但是我想要的是能够更新ITEM的任何字段或属性,并获取我不更新的字段的默认db值。
作为ITEM模型中的信息,我有: - 价钱 - 名称 - 牌 -说明 -类别 -_id
我的一个朋友向我解释说我必须使用Async / await,因为我必须首先检索我不想更新的特定字段的值,然后通过指示该值未更新的情况来处理取而代之的是此检索值。
我尝试过,但是我对应该使用async / await的方式有些困惑,因此我无法使其正常工作。
const update = (req, res) => {
const { id } = req.params
const { price, name, brand, description, category } = req.body
const currCat = await Item.findById(id, (err, item) => err ? res.send(err) : res.send(item.category))
//console.log(currCat)
Item
//attempt to get default category value - .findById(id, (err, item) => err ? res.send(err) : res.send(item.category)
.findByIdAndUpdate(id, { price, name, brand, description, category }, {new: true})
.then(item => item ? res.send(item) : res.status(404).send({message: "item not found with id : " + id}))
.then(item => item.category == null ? res.send(currCat) : res.send({message: "the category was specified so np"}))
}
现在,如果对currCat声明行和最后一个.then行进行注释,则事情可以像以前一样工作,这可以更新所有内容,但是如果JSON post request正文中没有一个或另一个字段,则将其设置为“ null”值。 / p>
这是JSON POST请求:
{
"price": 34,
"name": "I just changed your name",
"brand": "5d57fa1eaf168b29a4b1c00b",
"description": "I changed the value again"
}
这是打印的内容:
{
"_id": "5d631112e2fc2d39f21c334b",
"price": 34,
"name": "I just changed your name",
"brand": "5d57fa1eaf168b29a4b1c00b",
"description": "I changed the value again",
"category": null,
"__v": 0
}
我非常确定它只能在异步等待状态下解决,但无法正常工作,请帮助我! :)
编辑:
以下是我使用您的方法的结果:
在这里,您可以看到我没有放置类别字段,因为我想保留对象中已经存在的默认值
{
"price": 34,
"name": "I just changed your name",
"brand": "5d57fa1eaf168b29a4b1c00b",
"description": "I changed the value again"
}
这是结果:
(node:11759) UnhandledPromiseRejectionWarning: ValidationError: Item validation failed: category: Path `category` is required.
at new ValidationError (/home/eternano/Documents/JS/InventoryApp/node_modules/mongoose/lib/error/validation.js:30:11)
at model.Document.invalidate (/home/eternano/Documents/JS/InventoryApp/node_modules/mongoose/lib/document.js:2317:32)
at p.doValidate.skipSchemaValidators (/home/eternano/Documents/JS/InventoryApp/node_modules/mongoose/lib/document.js:2166:17)
at /home/eternano/Documents/JS/InventoryApp/node_modules/mongoose/lib/schematype.js:1037:9
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
(node:11759) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11759) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
PUT /inventory/update/5d631112e2fc2d39f21c334b - - ms - -
答案 0 :(得分:0)
因此无需同时使用findById和findByIdAndUpdate。 如果要使用findById,则可能需要手动更新字段,并且应该向函数添加异步标志并使用http-errors模块处理错误,如下所示:
const createError = require('http-errors');
const update = async (req, res) => {
const {id} = req.params;
const {price, name, brand, description, category} = req.body;
const item = await Item.findById(id);
if (!item) {
throw createError(404, `Item not found with id ${id}`);
}
item.price = price;
item.name = name;
// and so on for the others...
return item.save();
};
另一种方法是使用updateOne(),您也可以在猫鼬的docs中看到它的工作原理。
希望这会有所帮助!