Andi Aleksandrov
Andi Aleksandrov

Reputation: 633

Create a Mongoose schema that is not required, of type string, with enum and default null?

Is it possible to set up a mongoose schema that fulfils the following requirements:

  1. is NOT required
  2. is of type "string" type: String
  3. has an enum enum: ['red', 'green']
  4. has a default set to null default: null

Upvotes: 1

Views: 598

Answers (2)

mes shahdat
mes shahdat

Reputation: 192

use mongoose middleware

ex:

const colorSchema = mongoose.Schema(
    {
        color: String
    }
)

//                      middleware
colorSchema.pre("save", function (next) {

    if (this.color == 'red' || this.color == 'green' || this.color == "blue") null
    else {this.color = null}
    next()
})


const ColorModel = mongoose.model('colour', colorSchema)

Upvotes: 0

Andi Aleksandrov
Andi Aleksandrov

Reputation: 633

So, I managed to figure it out. It became clear when I read a bit more and understood what happens when you define different things.


Goal: I want to have a mongoose schema property that's either null or string. If it's a string, I want to validate and check if the value is strictly equal to one of the values in the given array.


color: {
  type: String,
  enum: ['red', 'green'],
  default: null
}

This won't work. There are two scenarios:

  1. If the color property exists on the incoming object, then its value gets validated by the enum validator and all is good.
  2. If the color property does not exist on the incoming object, I want to save null as a value for color. In this case, the incoming property color is undefined, so whatever we've defined for the default is taken as the value to be set for color and like in the first scenario, it will be validated by the enum validator. Obviously, having null will result in an error. To avoid that, I replaced the enum validator with a custom validator.

color: {
  type: String,
  validate: (value: string | null) => {
    if (value === null) return true;
    
    return ['red', 'green'].includes(value); // you could use enum here
    // return Object.values(MyEnum).includes(value as MyEnum);
  },
  default: null
}

Our custom validator will always run, because according to Mongoose's docs, validators are not run on undefined values, which we won't have in any case.

Note: The only exception to Mongoose's rule is the required validator, which will guarantee that color won't be undefined when other validators run. But that is not my case. I want color to be optional. My reason is I don't want the front-end to make sure and send it if it's not required by business logic.

Upvotes: 1

Related Questions