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?