Search code examples
javascriptnode.jsprototypemongoose

How to extend Query object in mongoose


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.