Mladen
Mladen

Reputation: 2210

How to define non-required field in Mongoose schema with nested "type" property?

I have the following Mongoose schema definition in my project:

export const ProductSchema: SchemaDefinition = {
  type: { type: String, enum: constants.productTypes, required: true },
  name: { type: String, required: false },

  espData: {
    type: { type: String, required: true },
    text: { type: String, required: true }
  },

  error: {
    type: {
      message: { type: String, required: true },
      statusCode: { type: Number, default: null }
    },
    required: false
  }
  // Some more definitions...
};

What's important from here is that I have collection of products where each product has its own type (which is a required string property that can have values defined in constants.productTypes), a non-required name field and so on. Also, there's espData field that has its own mandatory type property which is completely different from the top level type. And, there's error property that does not exist at all times, but when it does, it must have message property and optional statusCode property.

I now have to modify this schema so that espData becomes optional field since I may now have products that don't have this property. How do I do that? I tried couple of things, but none of them worked:

  espData: {
    type: {
      type: { type: String, required: true },
      text: { type: String, required: true }
    },
    required: false
  },

But, this is not working, most probably because there's so many nested type properties. Funny thing is that it perfectly works for the error property which has the same structure as espData, but without nested type property. The code I used is

    const model = new this.factories.product.model();
    model.type = 'hi-iq';
    // model.espData purposely left undefined
    await model.save();

The error I'm getting is Product validation failed: espData.type.text: Path 'espData.type.text' is required., espData.type.type: Path 'espData.type.type' is required. This indicates that model created from schema is created as espData.type.type which is not what I wanted (I wanted espData.type).

So, how do I define espData as an optional field, which must have type and text properties when it exists?

Upvotes: 0

Views: 2789

Answers (1)

paperba1l
paperba1l

Reputation: 191

Is this what you want. Create a new Document Schema with all the validations and nest it in another Schema with required: false (its default to false anyway)

const EspDataSchema = new Schema({
  type: { type: String, required: true },
  text: { type: String, required: true },
},
  {
    _id: false,
  }

);

example


export const ProductSchema = new Schema({

...
   espData: {
    type: EspDataSchema,
    required: false
   },

...

})

Upvotes: 1

Related Questions