I have an instance method in Mongoose where I need to perform Mongo's $inc operator on a field. My understanding is that since v3, Mongoose does not support $inc in any form other than an update method (e.g. there's no Mongoose method to take a Mongoose document object's field and perform $inc on it, then call save in a way that would avoid race conditions)
The callback function needs an updated user object with the update changes reflected. However, updating in this way does not update the original document from which we are performing the instance method. It's balance and purchases fields remain untouched.
usersSchema.methods.completePurchase = function(item, incBalance, cb) {
return this.update({
$addToSet: {
"purchases": item
},
$inc: {
"balance": incBalance
}
}, function(err) {
// I NEED THE UPDATED USER AT THIS POINT
return cb(err);
});
};
As an alternate, I've tried to call findByIdAndUpdate on the model itself, which returns the updated document. Then I leave it up to the calling method to do something useful with the returned updated user object.
usersSchema.methods.completePurchase = function(item, incBalance, cb) {
var model;
model = this.model(this.constructor.modelName);
return model.findByIdAndUpdate(this._id, {
$addToSet: {
"purchases": item
},
$inc: {
"balance": incBalance
}
}, function(err, updatedUser) {
// CRASHES BEFORE REACHING THIS POINT
return cb(err, updatedUser);
});
};
But doing this results in the following error
project/node_modules/mongoose/node_modules/mquery/lib/utils.js:26
if (/ObjectI[dD]$/.test(obj.constructor.name)) {
^
RangeError: Maximum call stack size exceeded
What is the proper way to perform an $inc or $addToSet call within a Mongoose instance method that will make the updated document accessible?