Использование lodash cloneDeep () для результата mongoose - не удается обновить полученный JSON - PullRequest
0 голосов
/ 04 ноября 2018

Используемые технологии: 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 голосов
/ 05 ноября 2018

Метод, который вы будете использовать для того, чтобы мангусты были довольны отслеживанием изменений и т. Д., Будет использовать set .

Однако я очень сомневаюсь, что клонирование объекта и использование множества было бы чем-то отдаленно близким к лучшей практике.

Почему бы просто не создать другую модель? Зачем обходить сборку в отслеживании изменений и т.д. в мангусте путем клонирования?

Вы также можете просто использовать toObject вашей новой модели mongoose ... пропустить клонирование ... изменить значения и т.д. ... затем просто передать этот объект в new Model(yourObjectWithChanges) и затем сохранить:

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