1
votes

I'm very new to web development. I'm trying to make a contact us form which when a user clicks submit the contents of the form should be sent to an email. I followed this youtube video : https://www.youtube.com/watch?v=EPnBO8HgyRU

When I try to post to my backend url (http://localhost:3001/api/contactus) via Postman it does send an email but all the 'req.body's come back undefined in the email. When I post from the frontend contact us form, I get this error in the console: console error

I do not understand what I am doing wrong. As I said I'm new to web development. I'm learning as I do so I have no idea what I don't know hence I believe it is a very simple fix probably but it is beyond me.

Here is my frontend code for the form I think things are going wrong when I bring in 'axios'.

async handleSubmit(e) {

  e.preventDefault();

  const err = this.validateForm();
  if (err) {

    if (this.state.userName.length < 2) {
      this.setState({
         userNameError: true,
      });
    }

    if (this.state.email.indexOf("@") === -1) {
      this.setState({
         emailError: true,
      });
    }


    if (this.state.subject.length < 2) {
      this.setState({
         subjectError: true,
      });
      }

     if (this.state.message.length < 2) {
       this.setState({
          messageError: true,
       });
      }
  }

  if (!err) {

  const finalForm = {
    userName: this.state.userName,
    email: this.state.email,
    subject: this.state.subject,
    message: this.state.message,
  };

  if (this.state.imagePreviewUrl) {

    let newFileName = this.state.fileName.replace(/^C:\\fakepath\\/, "");

    finalForm.attachments = [{
      filename: newFileName,
      content: this.state.imagePreviewUrl.split("base64,")[1],
      encoding: 'base64',
    }]
 }


const contactus = await axios.post('/api/contactus', {finalForm})

  this.handleFormClear(e);
  this.setState({
    formSubmit: true,
  });
}

}

Also I want const contactus to take in 'finalForm' for the 'req.body's but for some reason that does not work. Help :(

Here is my backend code:

const express = require('express')
const bodyParser = require('body-parser')
const nodemailer = require('nodemailer')
const Form = express()

Form.use(bodyParser.json())
Form.use(bodyParser.urlencoded({ extended: false}))
Form.post('/api/contactus', (req, res) => {
  console.log(req.body);

const htmlEmail = `
<h3>Contact Details</h3>
<ul>
  <li>Name:${req.body.userName}</li>
  <li>Email:${req.body.email}</li>
  <li>Subject${req.body.subject}</li>
</ul>
<h3>Messages</h3>
<p>${req.body.message}</p>
`

const transporter = nodemailer.createTransport({
 host: 'smtp.gmail.com',
 port: 465,
 secure: true,
 auth: {
   user: '[email protected]',
   pass: 'xxxxxxxx',
 }


  });

   const mailOptions = {
     from: req.body.userEmail,
     to: '[email protected]',
     subject: req.body.subject,
     text: req.body.userMessage + '\n\n' + "Send your response to: " + req.body.userEmail,
     html: htmlEmail,
     attachments: req.body.attachments && req.body.attachments
   };

   transporter.sendMail(mailOptions, (error, info) => {
     if (error) {
       console.log(error.message)
     } else {
         console.log('Message Sent: %s' , info.message)
         console.log('Message URL: %s', nodemailer.getTestMessageUrl(info))
     }
   });

})

const PORT = process.env.PORT || 3001

Form.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})

Please help. Thank you!

New error image: updated error

4
As per SO guidelines, all error messages must be typed in as text, not posted as images. This allows people to copy paste the message into search engines, and is much easier to read. Text in images can be difficult to read, especially on mobile. Also images use more date, which can be an issue on mobile for many people. You can edit you post to fix. More info is available in the help section - SherylHohman

4 Answers

0
votes

as I see from your error, you are calling localhost:3000 instead of localhost:3001

0
votes

I followed this tutorial as well and got a similar problem. What solved it for me was running my client and serve simultaneously using the command npm run dev in the terminal. This is assuming in your projectName\package.json there is a script for dev (its in the tutorial around 5:20 https://www.youtube.com/watch?v=EPnBO8HgyRU&t=542s). If that doesn't immediately solve your problem try resolving any other warnings or errors that appear in your terminal and rerun the command.

0
votes

The error in the image linked at the very bottom of the original post shows the problem:

Failed to load http://localhost:3001/api/contactus: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 404.

This is a cross-origin resource sharing issue. Essentially, you are trying to access a resource from one domain (localhost:3001) from another (localhost:3000) when you haven't enabled this functionality in your Express JS server.

You can learn how to set up Express JS to allow CORS here:

https://www.w3.org/wiki/CORS_Enabled#In_ExpressJS

0
votes

you need to use 3001 port

axios.post('http://localhost:3001/api/contactus', {finalForm})