buunguyen / mongoose-deep-populate

Mongoose plugin to enable deep population of nested models ⛺
MIT License
469 stars 44 forks source link

Support mongoose promise providers #23

Closed xyleen closed 9 years ago

xyleen commented 9 years ago

Hey!

(probably) Due to mongoose issue #2688, introduced in version 4.1.0, this library does not work properly when using external promise libraries as promise providers for mongoose.

I've tested this with mongoose@4.1.2.

Here is a test case for using Q.js as a promise provider for mongoose:

var mongoose = require('mongoose');
mongoose.Promise = require('q').Promise;
mongoose.connect('mongodb://localhost/cm_DB',  { server: { poolSize: 20 } });

var FooSchema = new mongoose.Schema({
    name: String,
});
var Foo = mongoose.model('Foo', FooSchema);

var BarSchema = new mongoose.Schema({
    foo: { type: mongoose.Schema.Types.ObjectId, ref: 'Foo' },
});
var Bar = mongoose.model('Bar', BarSchema);

var BazSchema = new mongoose.Schema({
    bar: { type: mongoose.Schema.Types.ObjectId, ref: 'Bar' },
});
var Baz = mongoose.model('Baz', BazSchema);
var deepPopulate = require('mongoose-deep-populate');
BazSchema.plugin(deepPopulate);

var foo = new Foo({ name: 'foo1' });
var bar = new Bar({ foo: foo._id });
var baz = new Baz({ bar : bar._id });

var promise = foo.save().then(function () {
    return bar.save();
}).then(function () {
    return baz.save();
}).then(function () {
    return Baz.findOne({ _id: baz._id }).deepPopulate('bar.foo');
}).then(function (baz) {
    console.log(baz);
}).done();

This ends up in the following error:

/project/node_modules/q/q.js:155
                throw e;
                      ^
Can't use ES6 promise with mpromise style constructor

which can be further traced:

/project/node_modules/q/q.js:155
                throw e;
                      ^
Error: Can't use ES6 promise with mpromise style constructor
    at new ES6Promise (/project/node_modules/mongoose/lib/ES6Promise.js:21:9)
    at Query.exec (/project/node_modules/mongoose-deep-populate/lib/plugin.js:36:17)
    at /project/node_modules/mongoose/node_modules/mquery/lib/mquery.js:2348:10
    at new promise (/project/node_modules/q/q.js:682:9)
    at Query.then (/project/node_modules/mongoose/node_modules/mquery/lib/mquery.js:2347:17)
    at /project/node_modules/q/q.js:1184:21
    at runSingle (/project/node_modules/q/q.js:137:13)
    at flush (/project/node_modules/q/q.js:125:13)
    at process._tickCallback (node.js:448:13)

Also, passing test case for mongoose's internal promise library (mpromise):

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/cm_DB',  { server: { poolSize: 20 } });

var FooSchema = new mongoose.Schema({
    name: String,
});
var Foo = mongoose.model('Foo', FooSchema);

var BarSchema = new mongoose.Schema({
    foo: { type: mongoose.Schema.Types.ObjectId, ref: 'Foo' },
});
var Bar = mongoose.model('Bar', BarSchema);

var BazSchema = new mongoose.Schema({
    bar: { type: mongoose.Schema.Types.ObjectId, ref: 'Bar' },
});
var Baz = mongoose.model('Baz', BazSchema);
var deepPopulate = require('mongoose-deep-populate');
BazSchema.plugin(deepPopulate);

var foo = new Foo({ name: 'foo1' });
var bar = new Bar({ foo: foo._id });
var baz = new Baz({ bar : bar._id });

var promise = foo.save().then(function () {
    return bar.save();
}).then(function () {
    return baz.save();
}).then(function () {
    return Baz.findOne({ _id: baz._id }).deepPopulate('bar.foo');
}).then(function (baz) {
    console.log(baz);
});

promise.onReject(function (reason) {
    console.log(reason);
});
xyleen commented 9 years ago

The commit above will work only with mongoose > 4.1.2 - there should be some code added for the backwards compatibility.

buunguyen commented 9 years ago

Fixed and released in 2.0.0. Thanks for the detailed report and suggested fix.

xyleen commented 9 years ago

@buunguyen - thank you! :)

zekenie commented 9 years ago

Hey @buunguyen I'm using 4.2.3 and deep populate version 2.0.2. When I switch out the mongoose promise constructor for an ES6 promise, I get the same error. When I go into the code from your last commit and just return an ES6 promise it works fine. Any suggestions?

buunguyen commented 9 years ago

@zekenie it's a bug. Please try 2.0.3 and let me know.

zekenie commented 8 years ago

Works!