Mongoose: toObject and toJSON produces copy of _id field as id with getters set to true

Created on 5 Oct 2012  路  2Comments  路  Source: Automattic/mongoose

Calling toObject({getters:true}) causes a copy of _id to be inserted into the produced object as id, somewhat unexpectedly. This breaks the examples from the toObject documentation, which demonstrate using getters:true to modify an object's object and json output without introducing an id copy. Here's the example:

var mongoose = require('mongoose');

var schema = new mongoose.Schema({ name: String });
schema.path('name').get(function (v) {
    return v + ' is my name';
});
schema.set('toJSON', { getters: true });
var M = mongoose.model('Person', schema);
var m = new M({ name: 'Max Headroom' });
console.log(m.toObject()); // { _id: 504e0cd7dd992d9be2f20b6f, name: 'Max Headroom' }
console.log(m.toJSON()); // { _id: 504e0cd7dd992d9be2f20b6f, name: 'Max Headroom is my name' }
// since we know toJSON is called whenever a js object is stringified:
console.log(JSON.stringify(m)); // { "_id": "504e0cd7dd992d9be2f20b6f", "name": "Max Headroom is my name" }

Here's the output I'm getting:

pete:draw-with-friends peter$ node mongoose-test.js 
{ name: 'Max Headroom', _id: 506e07f3c37bee811b000001 }
{ name: 'Max Headroom is my name',
  _id: 506e07f3c37bee811b000001,
  id: '506e07f3c37bee811b000001' }
{"name":"Max Headroom is my name","_id":"506e07f3c37bee811b000001","id":"506e07f3c37bee811b000001"}

Switching the calls to { getters: true, virtuals:false } then makes the documentation example do as it should. I'm not sure why there is a virtual id value, or why setting only getters to true would implicity switch the output of virtuals from false to true, but it does seem to.

Most helpful comment

good catch. the docs are now updated.

An id getter is added by default to all documents b/c old versions of the driver return the binary string representation of ObjectIds instead of their hexString when calling toString. This is no longer the case. It would be nice to remove but for backwards compatibility we leave it in.

it may be disabled with your schema options: http://mongoosejs.com/docs/api.html#document_Document-id

"getters" includes both virtual and path getters.

All 2 comments

good catch. the docs are now updated.

An id getter is added by default to all documents b/c old versions of the driver return the binary string representation of ObjectIds instead of their hexString when calling toString. This is no longer the case. It would be nice to remove but for backwards compatibility we leave it in.

it may be disabled with your schema options: http://mongoosejs.com/docs/api.html#document_Document-id

"getters" includes both virtual and path getters.

Thanks! It's definitely puzzling when an example doesn't do what you expect. I have added {id:false} to my schemas, as I already had my own workaround for binary id objects.

Was this page helpful?
0 / 5 - 0 ratings