mongoosejs / mongoose-lean-getters

Apply getters on lean() documents: https://mongoosejs.com/docs/tutorials/lean.html
Apache License 2.0
10 stars 15 forks source link

`mongoose-lean-getters` not working properly with `find` properly , calls the getter method twice #1

Closed vivekdoshi2 closed 4 years ago

vivekdoshi2 commented 4 years ago

I am using lean, (This makes queries faster and less memory intensive, but the result documents are plain old JavaScript objects (POJOs),)

By default this will block all getters execution and provides POJO (plain old java object) so as a solution we can use mongoose-lean-getters as per the standard doc

Schema :

const mongooseLeanGetters = require('mongoose-lean-getters');
const rateSchema = new Schema({
    rate_photo: {
        type: String,
        get: getFullUrl
    }
);

rateSchema.plugin(mongooseLeanGetters);

const Rate = mongoose.model('rates', rateSchema);

module.exports = Rate;

function getFullUrl(url) {
    if (url != undefined) return `${process.env.ASSETS_URL}uploads/${url}`;
    else return '';
}

Issue :

model.Rate.find(condition).lean({ getters : true })

Output:

without getter :
"rate_photo": "rate/1574154457920-myw3schoolsimage.jpg",

With getter :
"rate_photo": "http://192.168.15.93:6600/assets/uploads/rate/1574154457920-myw3schoolsimage.jpg",

With lean:
"rate_photo": "rate/1574154457920-myw3schoolsimage.jpg",

With lean and findOne:
"rate_photo": "http://192.168.15.93:6600/assets/uploads/rate/1574154457920-myw3schoolsimage.jpg",

With lean and find: // <------------ ISSUE
expected result : 
    "rate_photo": "http://192.168.15.93:6600/assets/uploads/rate/1574154457920-myw3schoolsimage.jpg",
BUT GOT THIS :
    "rate_photo": "http://192.168.15.93:6600/assets/uploads/http://192.168.15.93:6600/assets/uploads/rate/1574154457920-myw3schoolsimage.jpg",

I have also found the reason behind the issue, in the npm package, they are calling getter twice via middleware 1st from pre and second from post and this is only for find method alone :

module.exports = function mongooseLeanGetters(schema) {
  const fn = applyGettersMiddleware(schema);
  schema.pre('find', function() { //<--------------- 1st HERE
    if (typeof this.map === 'function') {
      this.map((res) => {
        fn.call(this, res);
        return res;
      });
    } else {
      this.options.transform = (res) => {
        fn.call(this, res);
        return res;
      };
    }
  });

  schema.post('find', fn); //<--------------- 2nd HERE
  schema.post('findOne', fn);
  schema.post('findOneAndUpdate', fn);
};

So If I comment out one of them ti works great, but the code is there for some reason, so Is there any better way to go ahead ?

I have also posted the same question on StackOverflow to know if this is not plugin issue

vkarpov15 commented 4 years ago

Thanks for reporting, fix is in v0.1.2 :+1: