If I have the following schema:
const userSchema = new mongoose.Schema({
modules: {
type: Map,
of: {
name: {
type: String,
required: true
}
}
}
})
Theoretically, mongoose should validate the type of each UserModule when I create a new document, ensuring the required name property is present.
However, if I create a user with a module without the name property:
await User.create({ modules: { example: {} } })
No error is thrown. Normally, mongoose is able to correctly validate for required types.
Workarounds I can think of include either hardcoding the keys for each module (and not use a map) or including a validator on the modules map to check all modules have the required keys are present, none of which are ideal.
Is there a better way to check the type of map values?
You are providing a value ... this is a valid Map definition:
await User.create({
modules: {
example: {} // <-- this is a valid. Key is `example` value is {}
}
})
As far as Map not having validation. Map does validate the values only since the keys are always strings. Consider this schema:
var AuthorSchema = new Schema({
books: {
type: Map,
of: { type: Number },
default: { "first book": 100 }, // <-- set default values
required: true // <-- set required
}
})
// after mongoose.model('Author', AuthorSchema) etc ....
var author1 = new Author({ books: { 'book one': 200 } })
author1.save() // <-- On save this works
var author2 = new Author({ books: { 'book one': "foo" } })
author2.save() // <-- This fails validation with "Cast to number failed ..."
var author1 = new Author()
author1.save() // <-- default would set values and that would pass the `required` validation
If you want to require the map make sure you do not have values in the default etc.
You can also review the map tests @ github for more insight
And in those tests you can also see how to do a complex nested map:
var AuthorSchema = new Schema({
pages: {
type: Map,
of: new mongoose.Schema({ // <-- just nest another schema
foo: { type: Number }, // <-- set your type, default, required etc
bar: { type: String, required: true } // <-- required!
}, { _id: false }),
default: {
'baz': {
foo: 100, bar: 'moo' // <-- set your defaults
}
}
}
})
This would save as expected this:
{
"_id" : ObjectId("5cf1cf4b7f67711963e2406d"),
"pages" : {
"baz" : {
"foo" : 100,
"bar" : "moo"
}
}
}
Trying to save this would fail since bar is required:
var author = new Author({
"pages" : {
"baz" : { "foo" : 1 } // <-- no bar!
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With