mblarsen / mongoose-hidden

A Mongoose schema plugin for filtering properties you usually do not want to sent client-side like passwords and IDs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

describe('A document with nested documents when hiding', function() {

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.

@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