Mongoose save() not updating value in an array in database document

19,025

Solution 1

Maybe notify mongooose the dataset has changed like this :

doc.markModified('pathToYourAttribute') 

From the docs http://mongoosejs.com/docs/schematypes.html

person.anything = { x: [3, 4, { y: "changed" }] }; 
person.markModified('anything');

Hope it helps!

Solution 2

Refer to this issue. One way to solve this would be not to update your array via the classic array Index method. So do this

doc.array.set(index, value);

Instead of

doc.array[index] = value;

also view the FAQ and doc for more details.

Solution 3

I replaced the save method with this statement:

Client_data.Unit.updateOne({_id: unit._id},unit);
Share:
19,025
Suleman Mirza
Author by

Suleman Mirza

Updated on June 15, 2022

Comments

  • Suleman Mirza
    Suleman Mirza almost 2 years

    I am trying to update a document in a collection (units) using GUI and after it gets updated I want to update the value (user.Units which is an array of Unit names) in collection (users). If the array length is just 1 element it gets updated and also shows up in database and everything works well, but when Array of Units have more than one element , I try to update it through a for loop, it shows it gets updated but when I check the database it is still not updated.

    I really can't figure out why its not updating the database when I update the value through a loop.

    Whole Edit and update function:-

     edit_unit: function (req, res, next) {
        var Data = req.body;
    
        Client_data.Unit.findById(req.params.unitId, function (err, unit) {
            var error = false;
            if (err) {
                error = err;
            } else if (!unit) {
                error = "FATAL: unable to look up Unit #" + req.params.unitId;
            } else {
    
                switch(req.body.name) {
                    case 'Icon':
                        var Icon = unit.Icon;
    
                        User.find({"Units":Icon}, function (err, users) {
                            if (err)
                            console.log(err);
    
                            users.forEach(function (u) {
                                if (u.Units.length > 1) {
                                for (var i = 0; i <= u.Units.length; i++) {
                                   if(u.Units[i] == Icon) {
                                       u.Units[i] = req.body.value;
                                   }
                                }
                                }
                                else {
                                    u.Units = req.body.value;
                                }
                                u.save(u);
                            });
                        });
                        unit[req.body.name] = req.body.value;
                        break;
                    case 'Description':
                        unit[req.body.name] = req.body.value;
                        break;
                    default:
                        unit[req.body.name] = req.body.value;
                        break;
                }
                var data = JSON.stringify(req.body);
                unit.save();
    
                res.writeHead(200, {
                    'Content-Length': data.length,
                    'Content-Type':  'application/json'
                });
                res.end(data);
            }
        });
    }
    

    req.body:-

    { name: 'Icon',
      value: 'Health Utility 22c',
      pk: '5395ed107cd92dc40eaafb56' 
    }
    

    User Schema:-

    var userSchema = mongoose.Schema({
    UserName:     { type: String, required: true },
    Password:     { type: String },
    FirstName:    { type: String, required: true },
    LastName:     { type: String, required: true },
    CompanyName:  { type: String },
    PhoneNumber:  { type: Number },
    StartDate:    { type: Date,   required: true },
    EndDate:      { type: Date,   required: true, default: new Date('9999-12-12')  },
    ClientID:     { type: ObjectId, ref: 'Client', default: null },
    DepartmentID: { type: ObjectId, ref: 'Department' },
    ManagerID:    { type: ObjectId, ref: 'User', default: null},
    Units:        [ { type: String, required: true } ],
    UserList:      { type: Array, default:[]},
    Access:    [{ type: String, enum: ['DEMO', 'USER','MANAGER','ADMINISTRATOR','OWNER']}],
    Credentials:  { type: String },
    AFTE:         { type: Number},
    SessionID:    { type: String, default: null }
    }, { safe: true });
    
  • Suleman Mirza
    Suleman Mirza almost 10 years
    What would be "PathToYourAttribute".?, sorry I am a bit new to mongoose.
  • azium
    azium over 8 years
    @SungWonCho I suppose it's a needlessly expensive query to recursively update the memory locations of all nested references if they haven't changed. I'm surprised its not front and centre in the docs.. maybe I missed it!
  • Doa
    Doa about 7 years
    this doesn't work for an array of objects, which is the OP's situation. any modification for that?
  • Kaushik Thirthappa
    Kaushik Thirthappa over 4 years
    Thanks, this helped a lot. FYI from the mongoose documentation --- Built-in Date methods are not hooked into the mongoose change tracking logic which in English means that if you use a Date in your document and modify it with a method like setMonth(), mongoose will be unaware of this change and doc.save() will not persist this modification. If you must modify Date types using built-in methods, tell mongoose about the change with doc.markModified('pathToYourDate') before saving