What is the difference between this code:
const userSchema = new Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: false, unique: true },
address: [{ type: mongoose.Types.ObjectID, required: true, ref: "Address" }],
},
{
timestamps: true,
}
);
And this code:
const userSchema = new Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
phoneNumber: { type: Number, required: false, unique: true },
address: { type: [mongoose.Types.ObjectID], required: true, ref: "Address" },
},
{
timestamps: true,
}
);
NOTICE:
- In the first code, I surrounded the whole
address
object with square brackets. - In the second code, I only surrounded the
type
property of theaddress
with square brackets.
What I want to know is how that will impact the app's behavior. Is there any difference?
Thanks.
CodePudding user response:
They both declare an array-of-references, but there are some subtle differences.
Let's take this simple schema:
const userSchema = mongoose.Schema({
address: { type: [ String ], required: true, default: undefined }
});
const User = mongoose.model('User', userSchema);
This will apply the options (required
and default
) to the address
array-of-strings as a whole:
// This will fail validation:
// ValidatorError: Path `address` is required
const doc = new User({});
// This will pass validation:
const doc = new User({ address : [] });
Now change the position of the brackets in the schema:
const userSchema = mongoose.Schema({
address: [{ type: String, required: true, default: undefined }]
});
This will apply the options to the elements of the address
array:
// This will pass validation, `address` itself isn't required:
const user = new User({});
// This will also pass validation, for the same reason:
const user = new User({ address : [] });
// This will fail validation, because elements of the array are required to have a proper value
// ValidatorError: Path `address.0` is required
const user = new User({ address : [ '' ] });
EDIT: if you want to enforce that the address
field is always defined and has at least one element, you have to use a custom validator. For your schema, it would look like this:
address: {
type: [ mongoose.Schema.Types.ObjectID ],
ref: 'Address',
required: true,
default: undefined,
validate: a => Array.isArray(a) && a.length > 0
}