UPD:
Found this finally. The code below is perfectly valid. There was just a destructive update to Layouts.blocks in another module...
Something very odd is happening here.
Here's a relevant part of the Layouts schema
blocks: [{
full: {type: Boolean},
fields: [{type: String}]
}]
And .pre save middleware code of another model
Map.pre('save', function(next){
var that = this;
var Layouts = connection.model('layouts');
var openFields = ['one', 'two'];
Layouts.find({_company: that._company, object: that._id, default: true}, function(err, layouts){
if (err) return next(err);
var layout = layouts[0];
console.log(layout.blocks);
layout.blocks.set(0, {full: false, fields: openFields});
layout.markModified('blocks');
console.log(layout.blocks);
layout.save(function(err){
console.log('saved: ', err);
next(err);
});
});
});
console.log values are
[{ full: true, _id: 54147307f07097462fb93912, fields: [] }]
[{ full: false,
_id: 54147307f07097462fb93918,
fields: [ 'one', 'two' ] }]
saved: null
Then i inspect saved layout and get:
blocks: [ { full: false, _id: 54147307f07097462fb93918, fields: [] } ],
So, _id and full are saved, but fields are not!
Something similar happens if i do direct update with
Layouts.update({_company: that._company, object: that._id, default: true},
{$set: {'blocks.0.fields': openFields}},
function(err){
next(err);
});
Any suggestions?
I attempted to implement the same schema as you specified and tried to update my layout object in three different ways, all of them worked. Here is my implementation and tests. Can't see where you are wrong from the code that you have submitted.
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/layout-test');
var LayoutSchema = new mongoose.Schema({
blocks: [{
full: {type: Boolean},
fields: [{
type: String
}],
}],
});
var Layout = mongoose.model('Layout', LayoutSchema);
var LAYOUT_DATA = {
blocks: [
{full: true},
],
};
// Updating the object, setting the first item of blocks
var test1 = function() {
new Layout(LAYOUT_DATA).save(function(err, layout) {
Layout.update({
_id: layout._id
}, {
$set: {
'blocks.0.full': false,
'blocks.0.fields': ['one', 'two'],
},
}, function(err, nbrOfUpdates) {
Layout.findById(layout._id, function(err, layout) {
if (layout.blocks[0].fields.length === 0) {
throw Error();
}
});
});
});
};
// Replacing the old blocks with a new array
var test2 = function() {
new Layout(LAYOUT_DATA).save(function(err, layout) {
layout.blocks = [{
full: false,
fields: ['one', 'two'],
}];
layout.save(function(err, layout) {
if (layout.blocks[0].fields.length === 0) {
throw Error();
}
});
});
};
// Pushing a new object to the blocks array and splicing away the old one
var test3 = function() {
new Layout(layout).save(function(err, layout) {
layout.blocks.push({
full: false,
fields: ['one', 'two'],
});
layout.blocks.splice(0, 1);
layout.save(function(err, layout) {
if (layout.blocks[0].fields.length === 0) {
throw Error();
}
});
});
};