How to extend Query object in mongoose
Problem
I'be trying to add a chain method to the Query object called "paginate". If I add it to query.js I can use it without any problems. However, it's not a good idea to modify one of the core files.
I'm using this code I found with some modifications and want it to be part of the Query prototype, but I haven't had any success on making it work out of Query.js.
How can I accomplish this? Are there any docs on how to extends any of these core files through a module? I haven't found anything that works for me.
mongoose.Query.prototype.paginate = function(page, limit, cb) {
var model, query, skipFrom;
if (page == null) {
page = 1;
}
if (limit == null) {
limit = 10;
}
query = this;
model = this.model;
skipFrom = (page * limit) - limit;
query = query.skip(skipFrom).limit(limit);
if (cb) {
return query.run(function(err, docs) {
if (err) {
return cb(err, null, null);
} else {
return model.count(query._conditions, function(err, total) {
return cb(null, total, docs);
});
}
});
} else {
throw new Error("pagination needs a callback as the third argument.");
}
};
Solution
Turns out it was a lot easier than what I expected. This is what I did and it worked:
Created a paginate.js file with:
mongoose = require('mongoose');
mongoose.Query.prototype.paginate = function(aPageStart, aLimit, aCallback) {
var model, query;
if (aLimit == null) {
aLimit = 10;
}
query = this;
model = this.model;
query = query.skip(aPageStart).limit(aLimit);
if (aCallback) {
return query.run(function(aError, aDocs) {
if (aError) {
return aCallback(aError, null, null);
} else {
return model.count(query._conditions, function(aError, aTotal) {
return aCallback(null, aTotal, aDocs);
});
}
});
} else {
throw new Error("pagination needs a callback as the third argument.");
}
};
and just require it where needed (In my model in this case).
Then you can call this method as the last of the chain.
Cheers,
Marcos.
Discussion
Maybe you can use this module or look how they achieve it: mongoose-paginate
Another solution is to create a method to your schema like that:
Schema.statics.paginate = (page, limit, cb) ->
...
return query;
// or
Schema.statics.paginate = (query, page, limit, cb) ->
...
return query.exec();
This recipe can be found in it's original form on Stack Over Flow.