fonzane
fonzane

Reputation: 440

Unable to update properties in mongoose object using nestjs

Somehow I'm unable to update properties of a mongoose object I fetch from a MongoDB. I'm trying to follow this pattern: Mongoose Docs: Document

This is my code:

// note: getInstances just returns model.find()
let instances: InstanceDocument[] = await this.instanceService.getInstances();
instances.forEach(async (instance, index) => {
    console.log(instance);
    let deviceCount = await this.instanceService.getDeviceCount(instance._id);
    let elementCount = await this.instanceService.getElementCount(instance._id)
    instance.deviceCount = deviceCount;
    instance.elementCount = elementCount;
    await instance.save();
    console.log(deviceCount, elementCount, instance);
})

The console.log prints the correct values for deviceCount and elementCount, but the instance object remains unmodified. It still has the unupdated values it has in the database.

Note: this is not a duplicate entry of Unable to add properties to js object, as I'm not trying to create a new object and give it properties.

Upvotes: 1

Views: 717

Answers (2)

fonzane
fonzane

Reputation: 440

The code above works. I made a mistake in defining the objects schema. I missed @Prop() decorator for the properties I added. This code works:

let instances: InstanceDocument[] = await this.instanceService.getInstances();
let fetchingDone = new Subject();
fetchingDone.subscribe(instances => res.json(instances))

instances.forEach(async (instance, index) => {
  instance.deviceCount = await this.instanceService.getDeviceCount(instance._id);
  instance.elementCount = await this.instanceService.getElementCount(instance._id);
  await instance.save();
  if (index+1 === instances.length) fetchingDone.next(instances);
})

Upvotes: 0

Jeremy Thille
Jeremy Thille

Reputation: 26380

Two things :

  1. You can't use await inside an array method like forEach or map. It doesn't work (doesn't await). Use a for loop instead.

  2. Mongoose has this weird requirement that you must explicitely tell it that a nested key has been modified in order to save it. See this question

let instances: InstanceDocument[] = await this.instanceService.getInstances();

for(let instance of instances) {
    console.log(instance);
    instance.deviceCount = await this.instanceService.getDeviceCount(instance._id);
    instance.elementCount = await this.instanceService.getElementCount(instance._id);

    instance.markModified("deviceCount"); // this
    instance.markModified("elementCount"); // and this

    await instance.save();
    console.log(deviceCount, elementCount, instance);
}

Upvotes: 2

Related Questions