Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

this.constructor.populate is not a function #5703

Closed
simllll opened this issue Oct 11, 2017 · 9 comments
Closed

this.constructor.populate is not a function #5703

simllll opened this issue Oct 11, 2017 · 9 comments
Assignees
Milestone

Comments

@simllll
Copy link
Contributor

simllll commented Oct 11, 2017

report a bug

documen.populate({path: 'jobFilter._type', select: lang}).execPopulate(); fails with:

error TypeError: this.constructor.populate is not a function
    at Document.populate (/home/simon/Dev/Web/hokify-server/node_modules/mongoose/lib/document.js:2462:22)

Just call a document and try to populate something on it. This worked before, broken in latest version though.

node v.8.5.0
mongoose 4.12.1
I'm using bluebird with

const Promise = require('bluebird');
mongoose.Promise = Promise;

any idea what's going on here? has the syntax changed?

@simllll
Copy link
Contributor Author

simllll commented Oct 11, 2017

I've found the reason for this bug: I'm calling .populate(..).execPopulate() on a sub document.
E.g.
DocumentA

  • key1
  • key2

What I did was calling DocumentA.key1.populate(...).execPopulate().. this worked before, but does not anymore.

Not sure if this is intended, please just close it if this is correct - but then a better error message would be nice to have, now it just fails with this non saying "is not a function" error.

Thanks for mongoose 👍 !

@vkarpov15 vkarpov15 added this to the 4.12.3 milestone Oct 14, 2017
@vkarpov15 vkarpov15 added the needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue label Oct 14, 2017
@vkarpov15
Copy link
Collaborator

Thanks for reporting, will investigate. If you can provide a standalone script that reproduces your issue that would be very helpful 👍

@vkarpov15 vkarpov15 modified the milestones: 4.12.3, 4.12.4 Oct 16, 2017
@sobafuchs
Copy link
Contributor

I'm not able to reproduce this:

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;

const GITHUB_ISSUE = `gh-5703`;

exec()
  .then(() => {
    console.log('program successful');
    process.exit(0);
  })
  .catch(error => {
    console.error(`Error: ${ error }\n${ error.stack }`);
    process.exit(1);
  });

async function exec() {
  await mongoose.connect(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);

  const toySchema = new mongoose.Schema({
    color: String
  });
  const Toy = mongoose.model('Toy', toySchema);

  const childSchema = new mongoose.Schema({
    toy: { type: mongoose.Schema.Types.ObjectId, ref: 'Toy', required: true }
  });
  const Child = mongoose.model('Child', childSchema);

  const toy = await Toy.create({ color: 'blue' });
  let child = await Child.create({ toy: toy._id });

  child = await Child.findById(child._id);
  await child.populate('toy').execPopulate();
  console.log(`Toy: `, child.toy); // shows { _id: 69e6a6..., color: 'blue', __v: 0 }
}

@simllll can you see if the above script works for you?

@sobafuchs sobafuchs added can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue labels Oct 18, 2017
@vkarpov15 vkarpov15 removed this from the 4.12.4 milestone Oct 21, 2017
@sobafuchs
Copy link
Contributor

@simllll did you have a chance to see if that script works for you?

@sobafuchs sobafuchs added the stale label Nov 3, 2017
@simllll
Copy link
Contributor Author

simllll commented Nov 3, 2017

Sorry for the delay,it's still on my list. As far as I can tell,the script you provided works for me. I will try to build a case similar to my setup that caused the issue. I will let you know when I have more details!

@sobafuchs
Copy link
Contributor

ok thanks

@vkarpov15
Copy link
Collaborator

Closing for now, will re-open if additional info is provided

@simllll
Copy link
Contributor Author

simllll commented Nov 14, 2017

Right, I've found a reproducable code.. but again, I'm not even sure if this is maybe intended. All I know is that this DID work before, but does not anymore. The problem is that I've a model like this:

{
     values: {
            value: String,
            toy: { type: mongoose.Schema.Types.ObjectId, ref: 'Toy'}
     }
}

I've passed the "values" to a sub function that tried to populate "toy" then. It makes somehow sense to me now that this does not work (anymore) as this passed object is actually just a part / "sub mongoose object" and not the mongoose model itself.

see example code to see what I mean:

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird'); // just switched it to bluebird, does not actually matter

const GITHUB_ISSUE = `gh-5703`;

exec()
    .then(() => {
        console.log('program successful');
        process.exit(0);
    })
    .catch(error => {
        console.error(`Error: ${ error }\n${ error.stack }`);
        process.exit(1);
    });

async function exec() {
  await mongoose.connect(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
   const toySchema = new mongoose.Schema({
        color: String
    });
    const Toy = mongoose.model('Toy', toySchema);

    const childSchema = new mongoose.Schema({
        name: { type: String, select: false},
        values: {
            value: String,
            toy: { type: mongoose.Schema.Types.ObjectId, ref: 'Toy'}
        }
    });
    const Child = mongoose.model('Child', childSchema);

    const toy = await Toy.create({ color: 'blue' });
    let child = await Child.create({ 'values.value': 'hello', 'values.toy': toy._id });

    child = await Child.findById(child._id).select('+name');
    await child.values.populate('toy').execPopulate(); // does not work..
    //await child.populate('values.toy').execPopulate(); // works
    console.log(`Child: `, JSON.stringify(child,false,3));
}

Results in:
Error: TypeError: this.constructor.populate is not a function TypeError: this.constructor.populate is not a function

In case you consider this is a bug, reopen it please @vkarpov15

@vkarpov15 vkarpov15 reopened this Nov 15, 2017
@vkarpov15 vkarpov15 added bug? and removed can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. stale labels Nov 15, 2017
@vkarpov15 vkarpov15 added this to the 4.13.4 milestone Nov 15, 2017
@vkarpov15
Copy link
Collaborator

Ah ok, its because you're calling .populate() on a nested value. Thanks for the repro, will investigate.

@vkarpov15 vkarpov15 modified the milestones: 4.13.4, 4.13.5 Nov 17, 2017
vkarpov15 added a commit that referenced this issue Nov 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants