MongooseJS and the problem with adding new properties
Hold on Cowboy
This blog post is pretty old. Be careful with the information you find in here. The Times They Are A-Changin'
My setup is easy. Node.js, ExpressJS, MongooseJS.
The Problem
I was getting a list of objects from the MongoDB. Like this
// Find all items where owner in following array
Thing.find()
.where('owner').in(following)
.populate('owner')
.populate('comments.userId')
.sort('-updatedOn')
.limit(20)
.exec(callback);
In the callback
I was assigning the results to res.locals.things
for use in another middleware function.
In another middleware function I tried this
// Extend thing[i] with a new property called newProperty
for var i=0; i < res.locals.things.length; i++) {
res.locals.things[i].newProperty = 'hello';
}
When I would echo out my things
, newProperty
was not in there.
To make a long story short. You can’t add new properties to MongooseJS Models. The solution is to not have MongooseJS create Models from the query above, just plain old JavaScript Objects. This can be accomplished via the lean(true)
switch in the query. So now my query looks like this
// Find all items where owner in following array
Thing.find()
.where('owner').in(following)
.populate('owner')
.populate('comments.userId')
.sort('-updatedOn')
.limit(20)
.lean(true) // Only return JSON objects, not MongooseJS Models
.exec(callback);
Now I can extend the response with custom properties.
Additionally
I tried using MongooseJS virtual
attributes, but this would not let me save it to a new property. So this code crashed with an error of RangeError: Maximum call stack size exceeded
ThingSchema.virtual('newProperty').set(function(num) {
this.newProperty = num;
});