Search code examples
node.jsreactjsexpressmongoosefetch

Please, how do i stop ValidationError on react?


I'm having ValidationError: name: Path `name` is required., email: Path `email` is required., subject: Path `subject` is required., message: Path `message` is required. when i try to send a post request. I have tested the api using Postman and is working very well. I have console.logged the state and is working perfectly, I have also gone to the backend and removed the required from the schema and i tried send a post and it sent successfully but when i checked the database, it was only the id and default date that was sent. I have tried everything i know, i don't know what else to do. Please help me.

My react component

export class Contact extends Component {

  state = {
    
      name:'',
      email:'',
      subject:'',
      message:'',
 
    isSubtmit : false
  }

  handleChange = (e) =>{
    this.setState({
      [e.target.name] : e.target.value
      
    })
    console.log(this.state)
  }

  handleSubmit = (e) =>{
    console.log(this.state)
    e.preventDefault()
    if(!contact){
      console.log('invalid input')
    } else{
      
      const req = {
        method : 'POST', 
        header : {'Content-Type':'application/json'},
        body : JSON.stringify({
        name:this.state.name,
        email: this.state.email,
        subject: this.state.subject,
        message: this.state.message
        })
      }
     fetch('http://127.0.0.1:5000/contact/add', req)
     .then((res)=>res.json())
     .then(data=>console.log(data))
    }
   

The html

 <form >
          <div>
            <input name="name" onChange={this.handleChange} value={this.state.name} type="text" placeholder="Name:"/>
          </div>
          <div>
            <input name="email" onChange={this.handleChange} value={this.state.email} type="email" placeholder="Email:"/>
          </div>
          <div>
            <input name="subject" onChange={this.handleChange} value={this.state.subject} type="text" placeholder="Subject:"/>
          </div>
          <div>
          <textarea name="message" onChange={this.handleChange} value={this.state.message} name="message" placeholder="Message" cols="30" rows="5"></textarea>
          </div>
          <div className="form__btn">
          <button disabled={this.state.isSubtmit} onClick={()=>this.setState({isSubtmit:true})} onClick={this.handleSubmit}>
            {this.state.isSubtmit?'THANKS, SUBMITED': 'SUBMIT'}
            </button>
          </div>
           </form>

My mongoose Schema

const mongoose = require('mongoose')

const schema = mongoose.Schema

const contactSchema = new schema({
  name : {
    type: String,
    required : true,
    trim : true,
    unique : true
  },
  email : {
    type: String,
    required : true,
    trim : true,
    unique : true
  },
  subject : {
    type: String,
    required : true,
    trim : true,
    unique : true
  },
  message : {
    type: String,
    required : true,
    trim : true,
    unique : true
  },
  date : {
    type: Date,
    default:Date.now()
  },
})

const contact = mongoose.model('contact', contactSchema)

module.exports = contact

my express route

const express = require('express')
const Contact = require('../model/contacts')

// express router object 
const router = express.Router()

// post router to recieve what the user has sent to me

router.post('/add', (req, res)=>{
  const name = req.body.name
  const email = req.body.email
  const subject = req.body.subject
  const message = req.body.message
  
  const item = new Contact({
    name,
    email,
    subject,
    message
  })
 
     item.save()
    .then(()=>res.json('item added'))
  
    .catch((error)=>res.status(400).json(`error : ${error}`))

})

module.exports = router

The api am sending to http://127.0.0.1:5000/contact/add

The complete error messsage from the backend

(node:16220) UnhandledPromiseRejectionWarning: ValidationError: contact validation failed: name: Path `name` is required., email: Path `email` is required., subject: Path `subject` is required., message: Path `message` is required.
[1]     at model.Document.invalidate (C:\Users\DELL\IMV\node_modules\mongoose\lib\document.js:2626:32)
[1]     at C:\Users\DELL\IMV\node_modules\mongoose\lib\document.js:2446:17
[1]     at C:\Users\DELL\IMV\node_modules\mongoose\lib\schematype.js:1225:9
[1]     at processTicksAndRejections (internal/process/task_queues.js:79:11)
[1] (node:16220) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[1] (node:16220) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are
not handled will terminate the Node.js process with a non-zero exit code.
[1] ReferenceError: item is not defined
[1]     at C:\Users\DELL\IMV\routes\contacts.js:25:6
[1]     at Layer.handle [as handle_request] (C:\Users\DELL\IMV\node_modules\express\lib\router\layer.js:95:5)
[1]     at next (C:\Users\DELL\IMV\node_modules\express\lib\router\route.js:137:13)
[1]     at Route.dispatch (C:\Users\DELL\IMV\node_modules\express\lib\router\route.js:112:3)
[1]     at Layer.handle [as handle_request] (C:\Users\DELL\IMV\node_modules\express\lib\router\layer.js:95:5)
[1]     at C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:281:22
[1]     at Function.process_params (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:335:12)
[1]     at next (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:275:10)
[1]     at Function.handle (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:174:3)
[1]     at router (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:47:12)
[1]     at Layer.handle [as handle_request] (C:\Users\DELL\IMV\node_modules\express\lib\router\layer.js:95:5)
[1]     at trim_prefix (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:317:13)
[1]     at C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:284:7
[1]     at Function.process_params (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:335:12)
[1]     at next (C:\Users\DELL\IMV\node_modules\express\lib\router\index.js:275:10)
[1]     at urlencodedParser (C:\Users\DELL\IMV\node_modules\body-parser\lib\types\urlencoded.js:100:7)

Please gurus, help me to figure out what the problem is, i'm very frustrated and crying right now.


Solution

  • The headers option is misspelled. It's missing an S in the end so the content is being sent as text/plain instead of application/json.

    Change:

    const req = {
       method : 'POST', 
       header : {'Content-Type':'application/json'},
       ...
     }
    

    To:

    const req = {
       method : 'POST', 
       headers : {'Content-Type':'application/json'},
       ...
     }