我的CRUD更新方法似乎无法部分更新我的字段

时间:2019-09-02 14:34:56

标签: javascript node.js mongodb express mongoose

我正在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 - -

1 个答案:

答案 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中看到它的工作原理。

希望这会有所帮助!