【问题标题】:Cannot Read property '_id' of undefined while using mongoose findOneandUpdate使用猫鼬 findOneandUpdate 时无法读取未定义的属性“_id”
【发布时间】:2020-09-03 15:32:03
【问题描述】:

我正在使用 mean.io 制作体育赛事管理系统。我正在尝试使用 rest api 更新模型 Player,它会从 mongoose 抛出此错误:

  { _id: 5411c79895d600440c698fa1,
  email: 'abc@bcd.com',
  name: 'James Bond',
  username: 'james.bond',
  games: [ 5411bd54786cfe2420f1e27a ],
  teams: [],
  roles: [ 'authenticated' ] }

[TypeError: Cannot read property '_id' of undefined]

PUT /api/players/5411c79895d600440c698fa1 500 199.402 ms - 36

我也尝试从播放器中删除 _id 属性,但它也不起作用。 我用来更新模型播放器的方法是:

exports.update = function(req, res) {
    var player = req.player;
    player = _.extend(player, req.body);        
    console.log(player);

    Player.findOneAndUpdate(req.params.playerId, player,{new:true}, function (err, updatedPlayer) {
        console.log(err);
        if (err) {
            return res.status(500).json({
                error: 'Cannot update the player'
            });
        }
        res.json(updatedPlayer);
    });

而且如果我使用mean.io 的默认包article 中提供的model.save 方法,它会显示另一个错误。我在播放器包app.js 文件中扩展了user 模型。因此,每当我尝试更新一个字段时,我在app.js 中声明的字段都是必需的,并且会抛出来自猫鼬的 path required 错误。

【问题讨论】:

    标签: node.js mongoose mean.io


    【解决方案1】:

    您的更新请求中有两个问题。

    首先,findOneAndUpdate 需要一个字典作为查询,而不仅仅是 id,所以你应该给它{_id: req.params.playerId}

    其次,将 mongoose 对象作为更新数据传递是有风险的,相反,您应该将其转换为像 var _player = player.toObject() 这样的字典,然后将 _player 传递给更新请求。请记住,您需要删除_player_id 参数,因为您无法更改文档的_id。在进行更新之前,只需执行delete _player._id 就可以了。此外,new 默认设置为true,因此您不需要选项字典。

    这是你的工作代码:

    var player = _.extend(req.player, req.body);        
    var _player = player.toObject();
    delete _player._id;
    
    var query = {_id: req.params.playerId};
    Player.findOneAndUpdate(query, _player, function (err, updatedPlayer) {
        ...
    });
    

    但在这种情况下,您甚至不必执行第一个操作。既然你只想更新req.body的数据,你可以这样做:

    var query = {_id: req.params.playerId};
    var data = {
        $set: req.body,
    };
    Player.findOneAndUpdate(query, data, function (err, updatedPlayer) {
        ...
    });
    

    这将使用来自req.body 的值更新与query 匹配的玩家的所有字段。

    【讨论】:

    • 感谢toObject 伙伴。干杯。一直在弄清楚为什么我不能从查询的文档中查询document.something._id,即使JSON.stringify(model.something) 显示something 上有_id 字段。
    猜你喜欢
    • 1970-01-01
    • 2016-11-12
    • 2021-09-06
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 2013-06-19
    相关资源
    最近更新 更多