failed to populate a field in subdocument
AlbertHambardzumyan opened this issue · comments
Works fine with v1.6.2.
Failed to populate the field of subdocument (array) after upgrading to v1.7.1
// crm-account contact
const CrmContactSchema = new mongoose.Schema({
link: { type: mongoose.Schema.Types.ObjectId, ref: ‘Users’ },
username: { type: String, maxlength: 50 }
}, { timestamps: true })
// crm-account
const CrmAccountSchema = new mongoose.Schema({
name: { type: String, maxlength: 50 }
contacts: [CrmContactSchema]
}, { timestamps: true })
// request
getCrmAccountContactsPopulated (id, companyId) {
const conditions = { _id: id, companyId }
const projection = {}
return CrmAccountsModel.model.findOne(conditions, projection)
.populate(‘contacts.link’, ‘id username firstName lastName profilePictureUrl title callingCode workPhone’)
}
Getting an empty object in contacts array.
{
name: ...
contacts: [{}]
}
HI @AlbertHambardzumyan I wont be able to look at this issue for the next two weeks (flying out to get married). Do you mind trying to create a new test case that produces this error. You can take inspiration from this test case that also tests embedded documents:
Line 648 in 6abcb01
The difference here is that it is not an array.
I tried to change the above test to use:
company: Company.schema
instead of this (which passes the test):
company: {
type: Schema.ObjectId,
ref: ‘Company’,
}
Perhaps something like this will work for you as well.
In the meantime, please use the version before 1.7.
Subdocument has to be an array of documents. It fails to fetch subdocument item fields if you apply populate on one of the fields of subdocument item.
it("shouldn't populate subdocument item", function(done) {
mongoose.modelSchemas = {}
mongoose.models = {}
let Company = defineModel(
'Company',
{
name: String,
code: String,
},
{ hideObject: false },
{}
)
let User = defineModel('User', {
name: String,
email: String,
companies: [{
description: { type: String },
link: { type: Schema.ObjectId, ref: 'Company' }
}],
password: {
type: String,
hide: true,
},
})
let company = new Company(testCompany)
let user = new User(testUser)
company.save(function(err, freshCompany) {
user.companies = { description: 'mock-description', link: company._id}
user.save(function() {
User.findOne()
.populate('companies.link')
.exec(function(err, freshUser) {
should.exist(freshUser.name)
should.exist(freshUser.email)
should.exist(freshUser.password)
should.exist(freshUser.companies)
should.exist(freshUser.companies[0])
should.exist(freshUser.companies[0].description) // failed
should.exist(freshUser.companies[0].link) // failed
let userJson = freshUser.toJSON()
should.not.exist(userJson.password)
should.exist(userJson.name)
should.exist(userJson.email)
should.exist(userJson.companies)
should.exist(userJson.companies[0].description) // failed
should.exist(userJson.companies[0].link) // failed
done()
})
})
})
})
So, we result is
{
name: 'Joe',
email: 'joe@example.com',
companies: [ {} ]
}
v1.6.2 works fine for the case I have described in issue description.
It suppose to work for this one as well, which should be:
{
name: 'Joe',
email: 'joe@example.com',
companies: [
{
description: 'mock-description',
link: { name: ..., code: ... }
}
]
}
@AlbertHambardzumyan I’ve added a test case (see 6ab5173) the uses object refs to store nested documents. This works as expected, in you case, I understand you are interested in storing the full sub-document. This is what has broken and I’ll have to look at that. I’m not sure I understand the test case in your comments above. I suggest that you fork the repo and add the test case as a PR.
PR: #74
@AlbertHambardzumyan I've reverted part of the 1.7 changes that has to do with setPath your test passes now. Do you mind testing it before I publish a new version?
@mblarsen The test case fully covers the issue I've described, and I see it passes now. So, feel free to publish a new version.
@AlbertHambardzumyan thanks for the help with this. I've now published 1.8