I have a Mongoose model that looks like this:
var ProjectSchema = new Schema({
name: String,
slug: String,
dateCreated: { type: Date, default: new Date() },
dateUpdated: { type: Date, default: new Date() },
createdByUserId: Schema.Types.ObjectId,
screens: [Schema.Types.Mixed]
});
I have a class method that looks like this:
ProjectSchema.statics.saveElementProperties = function(slugName, screenIndex, elementId, props, callback) {
var Project = mongoose.model('Project');
var updateProject = function(project) {
// Init empty objects if missing
project.screens[screenIndex] = project.screens[screenIndex] || {};
project.screens[screenIndex].elements = project.screens[screenIndex].elements || {};
project.screens[screenIndex].elements[elementId] = project.screens[screenIndex].elements[elementId] || {};
// Apply properties
project.screens[screenIndex].elements[elementId] = "Dummy Project Data";
console.log('elements before save:', project.screens[screenIndex].elements);
project.save(callback);
};
Project.findOne({ slug: slugName }, function(err, project) {
if (!project) {
project = new Project({ name: slugName, slug: slugName });
}
updateProject(project);
});
};
This happens when I call the method saveElementProperties
:
- The first time I run this method, it works like it should; a new object is added to
project.screens[screenIndex].elements
both in runtime (the 'elements before save:' log statement) and when checking the MongoDB database with themongo
client. - The second time, a 2nd object is added to
project.screens[screenIndex].elements
in runtime, but this object is never persisted to MongoDB. - The third time, object 1 and 3 are visible in
project.screens[screenIndex].elements
in runtime, but the 3rd object is never persisted to MongoDB.
What causes this behavior?
MAJOR UPDATE: I rewrote the entire persistence mechanism to run less frequently, and instead replace the entire project.screens[screenIndex].elements
object with an updated structure:
ProjectSchema.statics.saveScreenProperties = function(slugName, screenIndex, elements, callback) {
console.log('saveScreenProperties:', slugName, screenIndex);
var Project = mongoose.model('Project');
var updateProject = function(project) {
// Init empty objects if missing
project.screens[screenIndex] = project.screens[screenIndex] || {};
project.screens[screenIndex].elements = elements;
// Mark as modified and save
project.markModified('screens.' + screenIndex);
project.save(callback);
};
Project.findOne({ slug: slugName }, function(err, project) {
if (!project) {
project = new Project({ name: slugName, slug: slugName });
console.log(' creating new project');
}
updateProject(project);
});
};
However, it still shows the same behavior - it stores the initial elements
object, but not later changes to it.