import mongoose from "mongoose";
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, "Please provide your name."],
minLength: [3, "Name must be at least 3 characters long"],
maxLength: [50, "Name cannot exceed 50 characters"],
trim: true,
index: true,
},
username: {
type: String,
required: [true, "Please provide a username."],
minLength: [3, "Username must be at least 3 characters long"],
maxLength: [30, "Username cannot exceed 30 characters"],
unique: [
true,
"This username is already taken. Please choose another one.",
],
lowercase: true,
trim: true,
index: true,
},
email: {
type: String,
required: [true, "Please provide your email address."],
unique: [
true,
"This email address is already registered. Please login or use a different one.",
],
lowercase: true,
trim: true,
},
password: {
type: String,
required: [true, "Please provide a password."],
minLength: [8, "Password must be at least 8 characters long"],
maxLength: [50, "Password cannot exceed 50 characters"],
},
},
{ timestamps: true }
);
export const User = mongoose.model("User", userSchema);
Can we use unique in this way?
I have seen mongoose docs, required, maxLength, minLength have been used there but unique is not there. Can you help me in this.
Is this correct or it is a good practice to use it in this way
Unfortunately, mongoose unique constraints are not the same a validators so you cannot pass custom error messages to them.
Mongoose uses a MongoDB unique index when you define a property as unique: true
so you can check for an E11000
error thrown by the native driver during document creation and respond with a custom message if you want.
Something like this:
app.post('/user', async (req, res) => {
try{
const newUser = await User.create({
name: req.body.name,
username: req.body.username,
email: req.body.email,
password: req.body.password
});
return res.status(201).json({
message: 'New User Created'
})
}catch(err){
console.log(err);
if(err.code === 11000){
const errorMessages = new Map([
['username', 'This username is already taken. Please choose another one.'],
['email', 'This email address is already registered. Please login or use a different one.'],
]);
return res.status(400).json({
error: errorMessages.get(Object.keys(err.keyPattern)[0])
})
}else{
return res.status(500).json({
error: 'Error on Server'
})
}
}
})
By creating const errorMessages = new Map()
you can store all of your custom duplicate key error messages in a Map
object. Then to access the right one you can use the err.keyPattern
which will be an object of key: value
pairs. By calling Object.keys
on the err.keyPattern
you can select the key at 0 index and it will return the name of the property violating the unique index.