Skip to content

Commit

Permalink
fix(map): allow populating map of arrays like in 5.x
Browse files Browse the repository at this point in the history
Re: #12494
  • Loading branch information
vkarpov15 committed Oct 26, 2022
1 parent bd034fa commit 134d769
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
5 changes: 5 additions & 0 deletions lib/helpers/populate/assignVals.js
Expand Up @@ -52,6 +52,11 @@ module.exports = function assignVals(o) {

const _allIds = o.allIds[i];

if (o.path.endsWith('.$*')) {
// Skip maps re: gh-12494
return valueFilter(val, options, populateOptions, _allIds);
}

if (o.justOne === true && Array.isArray(val)) {
// Might be an embedded discriminator (re: gh-9244) with multiple models, so make sure to pick the right
// model before assigning.
Expand Down
20 changes: 16 additions & 4 deletions lib/types/map.js
Expand Up @@ -97,15 +97,27 @@ class MongooseMap extends Map {

const fullPath = this.$__path + '.' + key;
const populated = this.$__parent != null && this.$__parent.$__ ?
this.$__parent.$populated(fullPath) || this.$__parent.$populated(this.$__path) :
this.$__parent.$populated(fullPath, true) || this.$__parent.$populated(this.$__path, true) :
null;
const priorVal = this.get(key);

if (populated != null) {
if (value.$__ == null) {
value = new populated.options[populateModelSymbol](value);
if (Array.isArray(value) && this.$__schemaType.$isMongooseArray) {
value = value.map(v => {
if (v.$__ == null) {
v = new populated.options[populateModelSymbol](v);
}
// Doesn't support single nested "in-place" populate
v.$__.wasPopulated = { value: v._id };
return v;
});
} else {
if (value.$__ == null) {
value = new populated.options[populateModelSymbol](value);
}
// Doesn't support single nested "in-place" populate
value.$__.wasPopulated = { value: value._id };
}
value.$__.wasPopulated = { value: populated.value };
} else {
try {
value = this.$__schemaType.
Expand Down
41 changes: 41 additions & 0 deletions test/types.map.test.js
Expand Up @@ -1050,4 +1050,45 @@ describe('Map', function() {
const res = doc.toObject({ flattenMaps: true });
assert.equal(res.l1.l1key.l2.l2key.value, 'abc');
});

it('handles populating map of arrays (gh-12494)', async function() {
const User = new mongoose.Schema({
name: String,
addresses: {
type: Map,
of: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Address'
}],
default: {}
}
});

const Address = new mongoose.Schema({
city: String
});

const UserModel = db.model('User', User);
const AddressModel = db.model('Address', Address);

const address = await new AddressModel({ city: 'London' }).save();

const { _id } = await new UserModel({
name: 'Name',
addresses: {
home: [address._id]
}
}).save();

const query = UserModel.findById(_id);

query.populate({
path: 'addresses.$*'
});

const doc = await query.exec();
assert.ok(Array.isArray(doc.addresses.get('home')));
assert.equal(doc.addresses.get('home').length, 1);
assert.equal(doc.addresses.get('home')[0].city, 'London');
});
});

0 comments on commit 134d769

Please sign in to comment.