'mongoose put does not check for required field
I am making nodejs API and I have a user model. Some fields are required. When trigger post it will tell me that some fields required so no save will be done, but when I do it with put it will replace it even if validation is wrong, or even if there is a required field and is missing, but duplicates run good.
this is the model of user
const mongoose = require('mongoose');
const validator = require('validator');
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
firstName: {
type: String,
required: [true, 'the firstName is missing'],
validate: [(val) => validator.isAlpha(val, ['fr-FR']), 'not valid first name'],
},
lastName: {
type: String,
required: [true, 'the lastName is missing'],
validate: [(val) => validator.isAlpha(val, ['fr-FR']), 'not valid last name'],
},
phoneNumber: {
type: String,
required: [true, 'the phoneNumber is missing'],
unique: [true, 'phoneNumber already in use'],
validate: [(val) => validator.isMobilePhone(val,['ar-DZ']), 'not valid phone number'],
},
email : {
type: String,
required: [true, 'the email is missing'],
unique: [true, 'email already in use'],
validate: [validator.isEmail, 'not valid email'],
},
role: {
type : String,
"enum" : ['teacher', 'student'],
required : [true, 'the user `s role is missing'],
}
});
module.exports = mongoose.model('User', userSchema);
this is where I handle put
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const User = require('../../../../models/user');
router.put('/', (req, res) => {
//get the new user object
const userId = req.body.userId;
User.replaceOne({
_id: userId
},
{
_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role
})
.exec()
.then(response => {
res.status(200).json(response);
})
.catch(err => console.log(err));
});
module.exports = router;
so I tried to test those, by postman, I wanted from mongoose to do that automatically, I thought about splitting it and redirect it to delete then post, but i will need to do the checking first, or just do the checking manually, and because am using api, I don't want to use the patch method so I don't track the user for what changes he did in the front end.
Solution 1:[1]
You can, instead of replaceOne() use updateOne() or findOneAndUpdate() with turned on validators (as they are of by default), like so:
User.updateOne({_id: userId},
{
_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role
},
{runValidators: true})
.then(response => {
res.status(200).json(response);
})
.catch(err => console.log(err));
Or you can call the validate() on the new instance of the model and if it is valid continue with update logic, e.g.
let user = new User({_id: userId,
firstName: req.body.firstName,
lastName: req.body.lastName,
phoneNumber: req.body.phoneNumber,
email: req.body.email,
role: req.body.role});
user.validate()
.then(() => {
// update logic
})
.catch((err) => {
// handle error
})
Look for more information on Mongoose validation with update.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | perthos |
