// Hey, all. I’m just starting to use Mongoose, and I’ve run into something that doesn’t make sense.
// If I define a schema with an embedded document…
var SchemaA = new Schema({
topKey: String,
embedded : {
key: String
}
});
var ModelA = mongoose.model('ModelA', SchemaA),
thingA = new ModelA({ topKey: 'top level', embedded: { key: 'embedded' } });
// …its embedded document appears to share the schema and content with the top-level object:
console.log(thingA.embedded.embedded.embedded.key); // Prints "embedded" (what?)
console.log(thingA.embedded.embedded.topKey); // Prints "top level" (what???)
// What’s going on here? It also appears to share methods from the top-level schema.
// The app I’m building it into is CRUD over REST, and many documents have keys which should never be sent to the client — like a user’s password hash, or generated keys I use to find the document more easily (say, a value with case and punctuation removed). I noticed there was a problem problem when I defined a toJSON method on a schema which exports set of whitelisted keys. I thought it was a great idea:
var SchemaB = new Schema({
name: String,
embedded : {
key: String
}
});
SchemaB.publicKeys = ['embedded'];
SchemaB.method('toJSON', function(){
var out = {};
this.schema.publicKeys.forEach(function(key){
if (key in this) {
out[key] = this[key];
}
}, this);
return out;
});
var ModelB = mongoose.model('ModelB', SchemaB),
thingB = new ModelB();
// But calling it is an infinite loop, because when `embedded` is serialized, it turns out to have the same schema, with the same toJSON method, which finds an `embedded` key, and serializes it, forever and ever.
// console.log(JSON.stringify(thingB, null, '\t')); // RangeError: Maximum call stack size exceeded
// What’s going on with embedded documents?
// Is there a better way to export a set of keys from a model?
// Any insight is appreciated.
// -Sidney