Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose conditional required validation

I'm using mongoose and trying to set a custom validation that tells the property shall be required (ie. not empty) if another property value is set to something. I'm using the code below:

thing: {
type: String,
validate: [
    function validator(val) {
        return this.type === 'other' && val === '';
    }, '{PATH} is required'
]}
  • If I save a model with {"type":"other", "thing":""} it fails correctly.
  • If I save a model with {"type":"other", "thing": undefined} or {"type":"other", "thing": null} or {"type":"other"} the validate function is never executed, and "invalid" data is written to the DB.
like image 489
spirit Avatar asked Mar 29 '14 15:03

spirit


2 Answers

As of mongoose 3.9.1, you can pass a function to the required parameter in the schema definition. That resolves this problem.

See also the conversation at mongoose: https://github.com/Automattic/mongoose/issues/941

like image 84
Ron Wertlen Avatar answered Oct 08 '22 04:10

Ron Wertlen


For whatever reason, the Mongoose designers decided that custom validations should not be considered if the value for a field is null, making conditional required validations inconvenient. The easiest way I found to get around this was to use a highly unique default value that I consider to be "like null".

var LIKE_NULL = '13d2aeca-54e8-4d37-9127-6459331ed76d';

var conditionalRequire = {
  validator: function (value) {
    return this.type === 'other' && val === LIKE_NULL;
  },
  msg: 'Some message',
};

var Model = mongoose.Schema({
  type: { type: String },
  someField: { type: String, default: LIKE_NULL, validate: conditionalRequire },
});

// Under no condition should the "like null" value actually get persisted
Model.pre("save", function (next) {
  if (this.someField == LIKE_NULL) this.someField = null;

  next()
});

A complete hack, but it has worked for me so far.

like image 38
bloudermilk Avatar answered Oct 08 '22 03:10

bloudermilk