I have this code
var ClientSchema = new Schema({
name: {type: String, required: true, trim: true}
});
var Client = mongoose.mode(\'Client\', ClientSchema)
exports.updateGroup = (request, response, next) => {
const requestObj = request.body;
var conditions = {
_id: request.body._id,
communityId: request.body.communityId
};
var newValues = {
$set: requestObj
};
Group.updateOne(conditions, newValues, { ***runValidators: true*** }, (err, group) => {
if (err) return response.json({
message: "Updation of group failed",
error: err,
status: 500
});
response.json(group);
});
};
You need to add { runValidators: true } as the third argument for validation to work on update.
In your model, ex. Category.js file:
const CategorySchema = mongoose.Schema({
category_name : {
type : String,
required : [true, 'Category Name Is Required !'],
trim : true,
maxlength : [30, 'Category Name Is To Long !'],
unique : true,
});
const Category = module.exports = mongoose.model("Category",CategorySchema);
In your route file:
router.put("/",(req,res,next)=>{
Category.findOneAndUpdate(
{_id : req.body.categoryId},
{$set : {category_name : req.body.category_name} },
**{runValidators: true}**, function(err,result) {
if(err){
if(err.code === 11000){
var duplicateValue = err.message.match(/".*"/);
res.status(200).json({"defaultError":duplicateValue[0]+" Is Already Exsist !"});
}else{
res.status(200).json({"error":err.message} || {"defaultError":'Error But Not Understood !'});
}
}else{
console.log("From category.js (Route File) = "+result);
res.status(200).json({"success":"Category Updated Successfully!!"});
}
});
mongodb does not run validation on update by default. in order to make validation works by default when update also, just before connecting to mongodb you can set global setting only ones like that:
mongoose.set('runValidators', true); // here is your global setting
mongoose.connect(config.database, { useNewUrlParser: true });
mongoose.connection.once('open', () => {
console.log('Connection has been made, start making fireworks...');
}).on('error', function (error) {
console.log('Connection error:', error);
});
and any built-in or custom validation will run on update also
If you add this option in your config of mongoose it works:
mongoose.set('runValidators', true)
As of Mongoose 4.0 you can run validators on update()
and findOneAndUpdate()
using the new flag runValidators: true
.
Mongoose 4.0 introduces an option to run validators on
update()
andfindOneAndUpdate()
calls. Turning this option on will run validators for all fields that yourupdate()
call tries to$set
or$unset
.
For example, given OP's Schema:
var ClientSchema = new Schema({
name: {type: String, required: true, trim: true}
});
var Client = mongoose.model('Client', ClientSchema);
Passing the flag on each update
You can use the new flag like this:
var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, { runValidators: true }, function(err) {
....
});
Using the flag on a pre
hook
If you don't want to set the flag every time you update something, you can set a pre
hook for findOneAndUpdate()
:
// Pre hook for `findOneAndUpdate`
ClientSchema.pre('findOneAndUpdate', function(next) {
this.options.runValidators = true;
next();
});
Then you can update()
using the validators without passing the runValidators
flag every time.
You're not doing anything wrong, validation is implemented as internal middleware within Mongoose and middleware doesn't get executed during an update
as that's basically a pass-through to the native driver.
If you want your client update validated you'll need to find
the object to update, apply the new property values to it (see underscore's extend method), and then call save
on it.
Mongoose 4.0 Update
As noted in the comments and victorkohl's answer, Mongoose now support the validation of the fields of $set
and $unset
operators when you include the runValidators: true
option in the update
call.