16

While working with Node.js, Mongoose and MongoDB, I have found that my Mongoose schema getters and setters do not fire when I perform a findOne query.

I have found an old thread that suggests there was an issue with getters and setters in version 2.x, but it states that it has since been resolved and I'm using the very latest version of Mongoose (3.8.7).

Here's part of my schema

function testGetter(value) {
        return value + " test";
}

/**
* Schema
*/

var schema = new Schema({
        username: { type: String, required: true, unique: true, get: testGetter }
});

// I have also tried this.

schema.path('username').get(function (value, schemaType) {
        return value + " test";
});

Here's how I execute the query

Model
.findOne(conditions, fields, options)
.populate(population)
.exec(function (error, doc) {
        callback(doc, error);
});

It responds with a username value that lacks the " test" post-fix. Am I doing something wrong here? Any help would be greatly appreciated!

Additional information

This is the result of the find one:

{
    "username": "Radius"
}

This is the value of schema.paths.username.getters after applying one through one of the two ways described above:

[ [Function: testGetter] ]
Synzvato Chavea
  • 310
  • 1
  • 2
  • 7

3 Answers3

47

I was having the same problem with getters not modifying the returned documents when querying with Mongoose. To make this apply to every query, you can do this:

// Enable Mongoose getter functions
schema.set('toObject', { getters: true });
schema.set('toJSON', { getters: true });
Jamie S
  • 649
  • 6
  • 9
  • This worked for me. Thanks! However, can you explain why we need to mention the above for getters? The setters seems to work without enabling the Mongoose setter functions. – albin Apr 11 '16 at 13:10
5

Are you assuming virtuals are not working because they don't show up in your console.log output? If so, that is by design. Virtuals are external to your actual document so do not get printed with console.log by default. To get them to display, read these docs: http://mongoosejs.com/docs/api.html#document_Document-toObject

aaronheckmann
  • 10,625
  • 2
  • 40
  • 30
  • 1
    I wasn't watching console log entries, but I simply sent the doc back as a response. After reading the documentation snippet you gave me, I've changed `doc` to `doc.toObject({ getters: true, setters: true, virtuals: true })` and it's now working. Thanks a lot! – Synzvato Chavea Feb 18 '14 at 22:43
3

Try

schema.virtual('password').get(function () {
    return this.username;
});

as your getter function, this is your entity instance and the value parameter doesn't mean much here.

If you were writing a setter function, you would have to write this.username = value.

Tuxkowo
  • 31
  • 4
  • The main problem is that the getter I have is being ignored completely. It's not that the return value ends up empty. I've tried to apply your proposals to my code, but the getter remains unused. Thanks for your answer though! I'll add some clarifications to my original question. – Synzvato Chavea Feb 17 '14 at 16:27
  • Oh, also you can try using "virtual" instead of path. – Tuxkowo Feb 17 '14 at 16:31
  • I've tried using a virtual to overwrite the username path `schema.virtual('username').get(function () { ... });` and even tried creating a separate virtual `schema.virtual('test')` with "test" as its return value to see if virtuals work for me, but to no avail. – Synzvato Chavea Feb 17 '14 at 16:41