在猫鼬结果上使用lodash cloneDeep()-无法更新结果JSON

时间:2018-11-03 23:20:56

标签: node.js express mongoose lodash

使用的技术:Node.js,Express,Mongoose,Mocha,lodash

在测试我的服务时,我的应用程序:

  1. 从使用Mongoose保存新文档中获取结果
  2. 使用lodash.cloneDeep()克隆结果
  3. 尝试更改克隆实例的内容

结果是我得到了一个处于非常奇怪状态的克隆文档。尝试修改值时,如果我查询已更改的特定对象的值,它将显示正确的值。但是,当我只是将文档本身转储到控制台时,就好像我没有更新值一样。同样,如果我将文档传递到保存例程,它将把文档保存到MongoDb,就好像我没有更改任何值一样。

代码如下:

测试代码:

describe('### UPDATE ALARM', function () {
    it('Should save an alarm record for newly created asset', async () => {
        var asset = await Asset.findOne({ _id: compAdminAsset })
        const req = { user: { _id: compAdminId } }
        var alarm = await AlarmController.getByAsset(req, asset)
        expect(alarm._user).to.be.equal(compAdminId)
        expect(alarm._asset).to.be.equal(compAdminAsset)

        var newAlarm = _.cloneDeep(alarm)
        console.log('#### Newly Cloned Alarm Object')
        console.log(newAlarm)

        // change the rhSettings values
        newAlarm.rhSettings.rhAlarmLow = true
        newAlarm.rhSettings.rhAlarmHigh = true
        newAlarm.rhSettings.rhLow = 40
        newAlarm.rhSettings.rhHigh = 85

        console.log()
        console.log('#### Cloned Alarm Object AFTER updating values')
        console.log(newAlarm)

        console.log()
        console.log('####  Directly query the values that were changed ')
        console.log('newAlarm.rhSettings.rhAlarmLow: ' + newAlarm.rhSettings.rhAlarmLow)
        console.log('newAlarm.rhSettings.rhAlarmHigh: ' + newAlarm.rhSettings.rhAlarmHigh)
        console.log('newAlarm.rhSettings.rhLow: ' + newAlarm.rhSettings.rhLow)
        console.log('newAlarm.rhSettings.rhLow:  '+ newAlarm.rhSettings.rhHigh)

        var savedAlarm = await AlarmController.update(req, newAlarm)
        .
        .
        .
    })
})

测试代码的输出:

    ### UPDATE ALARM
#### Newly Cloned Alarm Object
{ rhSettings:
   { rhLow: 0, rhHigh: 80, rhAlarmLow: false, rhAlarmHigh: false },
  tempSettings:
   { tempLow: 50,
     tempHigh: 100,
     tempAlarmLow: false,
     tempAlarmHigh: false },
  _user: 'c86a7618-2323-48ec-b9e0-0d953301e37f',
  _asset: '6ca7a1ba-fc16-4cbf-9b4d-029c508d6b6c',
  _id: 5bde26a5038bec31683b8d80,
  createdAt: 2018-11-03T22:52:21.604Z,
  updatedAt: 2018-11-03T22:52:21.604Z,
  __v: 0 }

#### Cloned Alarm Object AFTER updating values
{ rhSettings:
   { rhLow: 0, rhHigh: 80, rhAlarmLow: false, rhAlarmHigh: false },
  tempSettings:
   { tempLow: 50,
     tempHigh: 100,
     tempAlarmLow: false,
     tempAlarmHigh: false },
  _user: 'c86a7618-2323-48ec-b9e0-0d953301e37f',
  _asset: '6ca7a1ba-fc16-4cbf-9b4d-029c508d6b6c',
  _id: 5bde26a5038bec31683b8d80,
  createdAt: 2018-11-03T22:52:21.604Z,
  updatedAt: 2018-11-03T22:52:21.604Z,
  __v: 0 }

#### Query the values that were changed directly
newAlarm.rhSettings.rhAlarmLow: true
newAlarm.rhSettings.rhAlarmHigh: true
newAlarm.rhSettings.rhLow: 40
newAlarm.rhSettings.rhLow:  85

返回“ newAlarm”对象的代码:

const Model = require('../models/alarm.model')

exports.getByAsset = async function (req, asset) {
    let newAlarm = new Model()
    newAlarm._asset = asset._id
    newAlarm._user = req.user._id
    newAlarm.rhSettings = asset.rhSettings
    newAlarm.tempSettings = asset.tempSettings
    return await newAlarm.save()
}

有什么想法导致克隆的JSON对象处于这种奇怪状态?

1 个答案:

答案 0 :(得分:2)

您可以使用set来使猫鼬对更改跟踪保持满意的方法。

但是,我高度怀疑克隆对象并使用set是否会接近最佳实践。

为什么不简单地创建另一个模型?为什么通过克隆绕过猫鼬的变更跟踪等构建?

您还可以简单地使用新的猫鼬模型的toObject ...跳过克隆...更改值等...然后只需将该对象传递给new Model(yourObjectWithChanges)然后保存:

var newAlarm = alarm.toObject() 
... do your changes
let newAlarmModel = new Model(newAlarm)
await newAlarmModel.save()