I am using Mongoose with Javascript (NodeJS) to read/write to MongoDB. I have a Document (Parent) that has a bunch of Subdocuments (Children) in it. Both my Document and Subdocuments have validation (required: true
and a function that validates that the user puts text in the field) defined in their Model.
When attempting to push a new Subdocument into the database, Mongoose rejects my push because validation fails on the Document. This has perplexed me as I am not trying to create a new Document with Subdocument, I am simply trying to push a new Subdocument into an existing Document.
Here is my (example) Mongoose Model:
const mongoose = require('mongoose');
const requiredStringValidator = [
(val) => {
const testVal = val.trim();
return testVal.length > 0;
},
// Custom error text
'Please supply a value for {PATH}',
];
const childrenSchema = new mongoose.Schema({
childId: {
type: mongoose.Schema.Types.ObjectId,
},
firstName: {
type: String,
required: true,
validate: requiredStringValidator,
},
lastName: {
type: String,
required: true,
validate: requiredStringValidator,
},
birthday: {
type: Date,
required: true,
},
});
const parentSchema = new mongoose.Schema(
{
parentId: {
type: mongoose.Schema.Types.ObjectId,
},
firstName: {
type: String,
required: true,
validate: requiredStringValidator,
},
lastName: {
type: String,
required: true,
validate: requiredStringValidator,
},
children: [childrenSchema],
},
{ collection: 'parentsjustdontunderstand' },
);
const mongooseModels = {
Parent: mongoose.model('Parent', parentSchema),
Children: mongoose.model('Children', childrenSchema),
};
module.exports = mongooseModels;
I can successfully push a new Child Subdocument into the Parent Document via the following MongoDB command:
db.parentsjustdontunderstand.update({
firstName: 'Willard'
}, {
$push: {
children: {
"firstName": "Will",
"lastName": "Smith",
"birthday": "9/25/1968" }
}
});
However, when I follow the Mongoose documentation Adding Subdocs to Arrays and try to add it via Mongoose, it fails.
For testing purposes, I am using Postman and performing a PUT request against an endpoint.
The following is req.body
:
{
"firstName": "Will",
"lastName": "Smith",
"birthday": "9/25/1968"
}
My code is:
const { Parent } = require('parentsModel');
const parent = new Parent();
parent.children.push(req.body);
parent.save();
What I get back is:
ValidationError: Parent validation failed: firstName: Path `firstName` is required...`
and it lists all of the Parent Document's validation requirements.
I could use some help on what I am doing wrong. For the record, I have looked at this answer on Stackoverflow: Push items into mongo array via mongoose but most examples I see do not show or discuss validation in their Mongoose Models.
EDIT 1
Based on feedback from @j-f, I modified my code to below (moving the body out of req.body
and just creating it in code for testing purposes. When I attempt to push the update the way recommended, the record gets inserted, however, I still get a validation error thrown to console:
const parent = await Parent.findOne({firstName: 'Willard'});
const child = {
children: {
"firstName": "Will",
"lastName": "Smith",
"birthday": "9/25/1968"
}
}
parent.children.push(child);
parent.save();
ValidationError: Parent validation failed: children.12.firstName: Path `firstName` is required., children.12.lastName: Path `lastName` is required., children.12.birthday: Path `birthday` is required.