I have a Mongoose Schema ready but when I call it with my api it gives out validation errors in all of the required fields
this is my schema object
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please use a name']
},
email: {
type: String,
required: [true, 'Please use a valid e-mail'],
unique : true,
lowercase: true,
validator: [validator.isEmail, 'Please provide a valid e-mail']
},
password: {
type: String,
required: [true, 'Please provide a password for your profile'],
minlength: 6
},
passwordConfirm: {
type: String,
required: [true, 'Please confirm your password']
}
})
const User = mongoose.model('User', userSchema)
the req. body i sent with the api through JSON is
{
"name": "user1",
"email": "user1#gmail.com",
"password": "pass1234",
"passwordConfirm": "pass1234"
}
I was trying to make a new user through the api and model throuth the controller
exports.signup = async (req, res, next) => {
try {
const newUser = await User.create(req.body)
console.log('in the newUser');
res.status(201)
.json({
status: 'success',
data: {
user: newUser
}
})
}catch (err){
res.status(400).json({
status: 'fail',
message: err
})
}
}
then I get the following errors in postman
{
"status": "fail",
"message": {
"errors": {
"passwordConfirm": {
"name": "ValidatorError",
"message": "Please confirm your password",
"properties": {
"message": "Please confirm your password",
"type": "required",
"path": "passwordConfirm"
},
"kind": "required",
"path": "passwordConfirm"
},
"password": {
"name": "ValidatorError",
"message": "Please provide a password for your profile",
"properties": {
"message": "Please provide a password for your profile",
"type": "required",
"path": "password"
},
"kind": "required",
"path": "password"
},
"email": {
"name": "ValidatorError",
"message": "Please use a valid e-mail",
"properties": {
"message": "Please use a valid e-mail",
"type": "required",
"path": "email"
},
"kind": "required",
"path": "email"
},
"name": {
"name": "ValidatorError",
"message": "Please use a name",
"properties": {
"message": "Please use a name",
"type": "required",
"path": "name"
},
"kind": "required",
"path": "name"
}
},
"_message": "User validation failed",
"name": "ValidationError",
"message": "User validation failed: passwordConfirm: Please confirm your password, password: Please provide a password for your profile, email: Please use a valid e-mail, name: Please use a name"
}
}
Just use required: true in your schema
If the validation fail, an error will be throw in:
const newUser = await User.create(req.body);
so you need to catch it and return an appropriate message to the user here (no in the model validation)
Related
getting the following error while sending a request from postman
I am trying to create a hotel but when I send my post request to the server I am getting this response saying 500 internal server error.I am not able to find any error in the code .Can anyone tell me what's the issue.
I am sending this request
localhost:8000/api/hotel
{
"errors": {
"cheapestPrice": {
"name": "ValidatorError",
"message": "Path `cheapestPrice` is required.",
"properties": {
"message": "Path `cheapestPrice` is required.",
"type": "required",
"path": "cheapestPrice"
},
"kind": "required",
"path": "cheapestPrice"
},
"desc": {
"name": "ValidatorError",
"message": "Path `desc` is required.",
"properties": {
"message": "Path `desc` is required.",
"type": "required",
"path": "desc"
},
"kind": "required",
"path": "desc"
},
"title": {
"name": "ValidatorError",
"message": "Path `title` is required.",
"properties": {
"message": "Path `title` is required.",
"type": "required",
"path": "title"
},
"kind": "required",
"path": "title"
},
"distance": {
"name": "ValidatorError",
"message": "Path `distance` is required.",
"properties": {
"message": "Path `distance` is required.",
"type": "required",
"path": "distance"
},
"kind": "required",
"path": "distance"
},
"address": {
"name": "ValidatorError",
"message": "Path `address` is required.",
"properties": {
"message": "Path `address` is required.",
"type": "required",
"path": "address"
},
"kind": "required",
"path": "address"
},
"city": {
"name": "ValidatorError",
"message": "Path `city` is required.",
"properties": {
"message": "Path `city` is required.",
"type": "required",
"path": "city"
},
"kind": "required",
"path": "city"
},
"type": {
"name": "ValidatorError",
"message": "Path `type` is required.",
"properties": {
"message": "Path `type` is required.",
"type": "required",
"path": "type"
},
"kind": "required",
"path": "type"
},
"name": {
"name": "ValidatorError",
"message": "Path `name` is required.",
"properties": {
"message": "Path `name` is required.",
"type": "required",
"path": "name"
},
"kind": "required",
"path": "name"
}
},
"_message": "Hotel validation failed",
"name": "ValidationError",
"message": "Hotel validation failed: cheapestPrice: Path `cheapestPrice` is required., desc: Path `desc` is required., title: Path `title` is required., distance: Path `distance` is required., address: Path `address` is required., city: Path `city` is required., type: Path `type` is required., name: Path `name` is required."
}
this is the model Hotel.js file
import mongoose from "mongoose";
const {Schema} = mongoose
const HotelSchema = new mongoose.Schema({
name:{
type:String,
required:true
},
type:{
type:String,
required:true
},
city:{
type:String,
required:true
},
address:{
type:String,
required:true
},
distance:{
type:String,
required:true
},
photos:{
type:[String],
},
title:{
type:String,
required:true
},
desc:{
type: String,
required:true
},
rating:{
type: Number,
min:0,
max:5
},
rooms:{
type:[String]
},
// for showing cheapest hotels
cheapestPrice:{
type:Number,
required:true
},
// for showing featured hotels
featured:{
type:Boolean,
deafult:false,
}
})
export default mongoose.model("Hotel",HotelSchema)
This is the route hotel.js
import express from "express"
import Hotel from "../models/Hotel.js";
const router = express.Router();
router.post("/", async (req,res)=>{
const newHotel = new Hotel(req.body);
try{
const savedHotel = await newHotel.save()
res.status(200).json(savedHotel)
}catch(err){
res.status(500).json(err)
}
})
export default router
This is the main index.js file
import express from "express"
import dotenv from "dotenv"
import mongoose from "mongoose"
import hotelRoute from './routes/hotels.js'
const app = express()
dotenv.config()
const connect = async () =>{
try{
await mongoose.connect(process.env.MONGO)
console.log("Connected to mongodb")
}catch(err){
throw err;
}
}
mongoose.connection.on("connected",()=>{
console.log("mongodb connected")
})
mongoose.connection.on("disconnected",()=>{
console.log("mongodb disconnected")
})
//Middleware
app.use(express.urlencoded({extended:true}))
app.use(express.json())
app.use("/api/hotel",hotelRoute)
app.listen(8000,() =>{
connect()
console.log("Connected to backend")
})
}
In the console I'm getting
Connected to backend
mongodb connected
Connected to mongodb
first you must check your req.body data.
you can validate your req.body with joi validator
and (or) express-joi-validation.
in mongoose you must generate a model from your schema:
const Kitten = mongoose.model('Kitten', kittySchema);
The post method URL = http://localhost:8800/api/hotels
try using http://
I have created a nodejs backend project with mongodb as the database. I want to create a document where it stores details of multiple students. Below shows my controller and model files.
Controller.js
const _user = new User({
username: req.body.username,
role: req.body.role,
hash_password: hash_password,
re_hash_password: req.body.re_hash_password,
student:{
member1: {
fullName: req.body.student.member1.fullName,
sliit_id: req.body.student.member1.sliit_id,
phone: req.body.student.member1.phone,
email: req.body.student.member1.email,
specialization: req.body.student.member1.specialization,
},
member2: {
fullName: req.body.student.member2.fullName,
sliit_id: req.body.student.member2.sliit_id,
phone: req.body.student.member2.phone,
email: req.body.student.member2..email,
specialization: req.body.student.member2.specialization,
},
}
Above shows the controller of my nodejs project. Here I want to add multiple members to my mongodb database with student object.
Model.js
const demoStudentSchema = new mongoose.Schema({
fullName: {
type: String,
required: true,
trim: true,
min: 3,
max: 30
},
sliit_id: {
type: String,
required: true,
trim: true,
min: 3,
max: 20
},
phone: {
type: String,
required: true
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true
},
specialization: {
type: String,
enum: ['SE','CSNE','DS', 'ISE', 'CS']
},
})
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
trim: true,
unique: true,
index: true,
min: 3,
max: 20
},
role: {
type: String,
required:true,
enum: ['student','supervisor','staff']
},
hash_password: {
type: String,
required: true,
},
re_hash_password: {
type: String,
required: true,
},
student: {
member1: {
demoStudentSchema
},
member2: {
demoStudentSchema
}
}
When I try to run this code using postman, below error occurs.
Postman request and error
{
"message": {
"errors": {
"email": {
"name": "ValidatorError",
"message": "Path `email` is required.",
"properties": {
"message": "Path `email` is required.",
"type": "required",
"path": "email"
},
"kind": "required",
"path": "email"
},
"phone": {
"name": "ValidatorError",
"message": "Path `phone` is required.",
"properties": {
"message": "Path `phone` is required.",
"type": "required",
"path": "phone"
},
"kind": "required",
"path": "phone"
},
"sliit_id": {
"name": "ValidatorError",
"message": "Path `sliit_id` is required.",
"properties": {
"message": "Path `sliit_id` is required.",
"type": "required",
"path": "sliit_id"
},
"kind": "required",
"path": "sliit_id"
},
"fullName": {
"name": "ValidatorError",
"message": "Path `fullName` is required.",
"properties": {
"message": "Path `fullName` is required.",
"type": "required",
"path": "fullName"
},
"kind": "required",
"path": "fullName"
}
},
"_message": "User validation failed",
"name": "ValidationError",
"message": "User validation failed: email: Path `email` is required., phone: Path `phone` is required., sliit_id: Path `sliit_id` is required., fullName: Path `fullName` is required."
}
}
I have gone through some videos and articles but couldnt find out any solution.
Could you please help me to find out the error and give your suggestions on solving this issue.
The following code gives an Validation error whenever the post/get request is made using postman. The image is also provided at the end of the code please check that out to debug this code.
****//this is my index file code****
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const dotenv =require("dotenv");
const mongoose = require("mongoose");
//importing the routes file
const Authroute = require("./routes/auth");
dotenv.config();
//middlewear
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.raw());
app.use("/api/users",Authroute);
//Connected to Db
mongoose.connect(process.env.Db_Connect,
{ useNewUrlParser: true, useUnifiedTopology: true }, () =>
{
console.log("connected to Db");
});
app.listen(4000, ()=> console.log("your system is up"));
**//this is auth file code**
const router = require("express").Router();
const Newposts =require("../Models/posts");
//post request
router.post("/register",async(req,res) =>
{
const com = new Newposts({
name:req.body.name,
email:req.body.email,
password:req.body.password,
});
try{
const savedUser = await com.save();
res.json(savedUser);
}
catch(err)
{
res.status(400).send(err);
}
});
module.exports = router;
error statement
"errors": {
"name": {
"name": "ValidatorError",
"message": "Path `name` is required.",
"properties": {
"message": "Path `name` is required.",
"type": "required",
"path": "name"
},
"kind": "required",
"path": "name"
},
"email": {
"name": "ValidatorError",
"message": "Path `email` is required.",
"properties": {
"message": "Path `email` is required.",
"type": "required",
"path": "email"
},
"kind": "required",
"path": "email"
},
"password": {
"name": "ValidatorError",
"message": "Path `password` is required.",
"properties": {
"message": "Path `password` is required.",
"type": "required",
"path": "password"
},
"kind": "required",
"path": "password"
}
},
"_message": "posts validation failed",
"name": "ValidationError",
"message": "posts validation failed: name: Path `name` is required., email: Path `email` is required., password: Path `password` is required."
}
posts file code
const mongoose =require("mongoose");
const NewUser = new mongoose.Schema({
name:{
type: String,
required:true,
min:6,
max:20
},
email:{
type: String,
required:true,
min:10,
max:200
},
password:{
type: String,
required:true,
min:6,
max:100
}
});
module.exports = mongoose.model("posts",NewUser);
[postman request link] Image
: https://i.stack.imgur.com/UiO74.png
Thank you for your time....
I dont know why i am getting a validator error response. I have tried to debug as much as possible but i cant see to find where the problem is. I have used the exact names i have used in my schema but still im getting the error in both postman and rest client
My server.js looks like this:
const app = express()
const mongoose = require('mongoose')
const dotenv= require('dotenv')
const routesUrls=require('./routes/routes')
const cors = require('cors')
dotenv.config()
mongoose.connect(process.env.DATABASE_ACCESS, () =>console.log("Database Connected"))
app.use(express.json())
app.use(cors())
app.use('/app', routesUrls)
app.listen(4000, () => console.log("server is up and running"))
My routes.js
const router = express.Router()
const signupTemplateCopy = require('../models/SignUpModels')
router.post('/signup/', (request,response) =>{
const SignedupUser = new signupTemplateCopy({
fullname:request.body.fullname,
username:request.body.username,
email:request.body.email,
password:request.body.password
})
SignedupUser.save().then(data =>{
response.json(data)})
.catch(error =>{
response.json(error)
})
})
module.exports = router ```
The Schema looks like this
```const mongoose = require('mongoose')
const signupTemplate = new mongoose.Schema({
fullname:{
type:String,
required:true
},
username:{
type:String,
required:true
},
email:{
type:String,
required:true
},
password:{
type:String,
required:true
},
date:{
type:Date,
default:Date.now
}
})
module.exports = mongoose.model('mytable', signupTemplate)
The error
"errors": {
"fullname": {
"name": "ValidatorError",
"message": "Path `fullname` is required.",
"properties": {
"message": "Path `fullname` is required.",
"type": "required",
"path": "fullname"
},
"kind": "required",
"path": "fullname"
},
"username": {
"name": "ValidatorError",
"message": "Path `username` is required.",
"properties": {
"message": "Path `username` is required.",
"type": "required",
"path": "username"
},
"kind": "required",
"path": "username"
},
"email": {
"name": "ValidatorError",
"message": "Path `email` is required.",
"properties": {
"message": "Path `email` is required.",
"type": "required",
"path": "email"
},
"kind": "required",
"path": "email"
},
"password": {
"name": "ValidatorError",
"message": "Path `password` is required.",
"properties": {
"message": "Path `password` is required.",
"type": "required",
"path": "password"
},
"kind": "required",
"path": "password"
}
},```
"_message": "mytable validation failed",
"message": "mytable validation failed: fullname: Path `fullname` is required., username: Path `username` is required., email: Path `email` is required., password: Path `password` is required."
}
make sure u have used the exact names in the POSTMANT and in the route.js
check the caps that was my issue
const router = express.Router();
const signUpTemplateCopy = require("../models/signupmodels");
router.post("/signup", (request, response) => {
const signedUpUser = new signUpTemplateCopy({
fullName: request.body.fullName,
userName: request.body.userName,
Email: request.body.Email,
password: request.body.password,
});
signedUpUser.save().then((data) => {
response.json(data).catch((error) => {
response.json(error);
});
});
});
module.exports = router;
router.post('/signup/', (request,response) => {
const { fullname, username, email, password } = request.body
const SignedupUser = new signupTemplateCopy()
SignedupUser.fullname = fullname;
SignedupUser.username = username;
SignedupUser.email = email;
SignedupUser.password = password;
SignedupUser.save()
.then(data => {
response.json(data)
})
.catch(error => {
response.json(error)
}) )}
You could give this a try.. I am fairly new to mongoDb, express, nodeJs, but I think a good practise is to put these kind of functions in a controller file.
Also, if using postman, make sure you set the headers, Content-Type -> Application/JSON. And that your raw body to send shoud look something like this...
{ "fullname": "John Doe", "username": "johndoe123", "email": "johndoe#gmail.com", "password": "123456 }
The below schema allows me to have the optionalField required if value is set to option1 but if value is set to option2 then optionalField can be set to anything the user desires. Instead, I want the validation to fail if value is set to anything other than option1 and optionalField is passed in.
const validValues = ['option1', 'option2']
const sampleSchema = new mongoose.Schema({
value: {
type: String,
enum: validValues,
required: true
}
optionalField: {
type: Number,
required: function() { return this.value === 'option1' }
// validation should fail if this property is passed in when value is anything but option1
}
})
Joi has an excellent way to achieve this using Joi.forbidden():
const validValues = ['option1', 'option2']
const schema = Joi.object({
value: Joi.string().valid(...validValues).required(),
optionalField: Joi.string().when('value', { is: 'option1', then: Joi.required() otherwise: Joi.forbidden() })
})
If I validate with this schema and optionalField is passed in to Joi, the validation will fail unless value is option1.
I am hoping to find a way to achieve the same in Mongoose.
Thank You!
You can use custom validators like this:
optionalField: {
type: Number,
required: function() {
return this.value === "option1";
},
validate: {
validator: function(v) {
console.log({ v });
return !(this.value !== "option1" && v.toString());
},
message: props =>
`${props.value} optionalField is forbidden when value is not option1`
}
}
Sample route:
router.post("/sample", (req, res) => {
const sample = new Sample(req.body);
sample
.save()
.then(doc => res.send(doc))
.catch(err => res.status(500).send(err));
});
Input 1:
{
"value": "option2",
"optionalField": 11
}
Result 1: (error)
{
"errors": {
"optionalField": {
"message": "11 optionalField is forbidden when value is not option1",
"name": "ValidatorError",
"properties": {
"message": "11 optionalField is forbidden when value is not option1",
"type": "user defined",
"path": "optionalField",
"value": 11
},
"kind": "user defined",
"path": "optionalField",
"value": 11
}
},
"_message": "Sample validation failed",
"message": "Sample validation failed: optionalField: 11 optionalField is forbidden when value is not option1",
"name": "ValidationError"
}
Input 2:
{
"value": "option2"
}
Result 2: (success)
{
"_id": "5e031b473cbc432dfc03fa0e",
"value": "option2",
"__v": 0
}
Input 3:
{
"value": "option1"
}
Result 3: (error)
{
"errors": {
"optionalField": {
"message": "Path `optionalField` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `optionalField` is required.",
"type": "required",
"path": "optionalField"
},
"kind": "required",
"path": "optionalField"
}
},
"_message": "Sample validation failed",
"message": "Sample validation failed: optionalField: Path `optionalField` is required.",
"name": "ValidationError"
}
Input 4:
{
"value": "option1",
"optionalField": 11
}
Result 4: (success)
{
"_id": "5e031ba83cbc432dfc03fa10",
"value": "option1",
"optionalField": 11,
"__v": 0
}