Do you want to request a feature or report a bug?
Might be a bug
What is the current behavior?
const TodoSchema: Schema = new Schema({
name: { type: String, required: true },
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Item',
required: true
}]
})
export default mongoose.model<ITodo>("Todo", TodoSchema)
const todo = new Item({
name: "My todo"
})
await expect(todo.validate()).rejects.toThrow("Todo validation failed: items: Path `items` is required.")
The test fails (last line), because validation is not enforced. Here's the failure:
expect(received).rejects.toThrow()
Received promise resolved instead of rejected
Resolved to value: undefined
If the current behavior is a bug, please provide the steps to reproduce.
See the code above
What is the expected behavior?
The test fails because an array of items isn't provided
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Node: 12.x
Mongoose: 5.9.25
MongoDB: 3.6
You should define your schema as below
const mongoose = require("mongoose")
mongoose.set('debug', true);
const connectionString = 'mongodb://localhost:27017/test_db';
console.log('version:: ', mongoose.version)
run()
.then(() => console.log('done'))
.catch(error => console.error(error))
.finally(() => {
process.exit(1)
})
async function run() {
await mongoose.connect(connectionString);
await mongoose.connection.dropDatabase();
mongoose.model('Item', new mongoose.Schema({ name: { type: String } }));
const schema = new mongoose.Schema({
name: { type: String, required: true },
items: {
type: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Item',
required: true
}],
validate: {
validator: function () {
return this.items && this.items.length > 0
},
message:() => `items should not be empty`
}
}
})
const M = mongoose.model('Test', schema);
const data = { name: 'abc' }
await M.create(data)
}
@bhrigushr is right. Mongoose arrays implicitly have a default value of []
: https://mongoosejs.com/docs/schematypes.html#arrays so if you don't specify items
, you'll get an empty array.
An alternative would be to make your array undefined by default:
const TodoSchema: Schema = new Schema({
name: { type: String, required: true },
items: {
// `items` is an array of non-nullable ObjectIds which is `undefined` by default
type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Item', required: true }]
default: void 0
}
})
See more info on void 0
Thanks, @bhrigushr's solution worked. That makes sense, but maybe it could be a bit more easier / straightforward.
@vkarpov15 I wasn't able to make that solution work. Too bad, because I like this conciseness.
Thanks both of you for your help anyway
@afillatre you're right, I made a typo in how I defined my schema. Fixed :+1:
Most helpful comment
You should define your schema as below