Skip to content

Commit a2040f6

Browse files
authored
Merge pull request #13386 from Automattic/vkarpov15/gh-13327-2
fix(document): handle set() from top-level underneath a map of mixed
2 parents 59a29a8 + be67d0f commit a2040f6

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

lib/document.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,11 @@ Document.prototype.$set = function $set(path, val, type, options) {
12501250
// allow changes to sub paths of mixed types
12511251
mixed = true;
12521252
break;
1253+
} else if (schema.$isSchemaMap && schema.$__schemaType instanceof MixedSchema && i < parts.length - 1) {
1254+
// Map of mixed and not the last element in the path resolves to mixed
1255+
mixed = true;
1256+
schema = schema.$__schemaType;
1257+
break;
12531258
}
12541259
}
12551260

@@ -1688,17 +1693,26 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
16881693
obj[parts[i]] = val;
16891694
}
16901695
} else {
1691-
if (utils.isPOJO(obj[parts[i]])) {
1692-
obj = obj[parts[i]];
1693-
} else if (obj[parts[i]] && obj[parts[i]] instanceof Embedded) {
1694-
obj = obj[parts[i]];
1695-
} else if (obj[parts[i]] && !Array.isArray(obj[parts[i]]) && obj[parts[i]].$isSingleNested) {
1696-
obj = obj[parts[i]]._doc;
1697-
} else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
1698-
obj = obj[parts[i]];
1696+
const isMap = obj instanceof Map;
1697+
let value = isMap ? obj.get(parts[i]) : obj[parts[i]];
1698+
if (utils.isPOJO(value)) {
1699+
obj = value;
1700+
} else if (value && value instanceof Embedded) {
1701+
obj = value;
1702+
} else if (value && !Array.isArray(value) && value.$isSingleNested) {
1703+
obj = value._doc;
1704+
} else if (value && Array.isArray(value)) {
1705+
obj = value;
1706+
} else if (value == null) {
1707+
value = {};
1708+
if (isMap) {
1709+
obj.set(parts[i], value);
1710+
} else {
1711+
obj[parts[i]] = value;
1712+
}
1713+
obj = value;
16991714
} else {
1700-
obj[parts[i]] = obj[parts[i]] || {};
1701-
obj = obj[parts[i]];
1715+
obj = value;
17021716
}
17031717
}
17041718
}

test/document.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12107,6 +12107,24 @@ describe('document', function() {
1210712107
const fromDb = await Test.findById(x._id).lean();
1210812108
assert.equal(fromDb.d.x.y, 1);
1210912109
});
12110+
12111+
it('can set() from top-level on path underneath map of mixed (gh-13327)', async function() {
12112+
const testSchema = new Schema({
12113+
c: {
12114+
type: Map,
12115+
of: 'Mixed'
12116+
}
12117+
});
12118+
const Test = db.model('Test', testSchema);
12119+
12120+
const x = new Test();
12121+
x.set('c.x.y', 1);
12122+
assert.strictEqual(x.get('c.x.y'), 1);
12123+
await x.save();
12124+
12125+
const fromDb = await Test.findById(x._id).lean();
12126+
assert.equal(fromDb.c.x.y, 1);
12127+
});
1211012128
});
1211112129

1211212130
describe('Check if instance function that is supplied in schema option is availabe', function() {

0 commit comments

Comments
 (0)