seriously
seriously

Reputation: 1367

post request returns empty object

I am trying to send form data to the backend using fetch API but when I console.log my request.body it returns an empty object {}. What I was trying to send to my backend was the firstname, lastname, email, and message the user inputted. Why isn't the object containing the data. Where did I go wrong. Any help is appreciated. Thanks in advance.

//backend
const express = require('express');
const app = express();

app.listen(3000, () => console.log('listening at port 3000'));
app.use(express.static('public'));
app.use(express.json({
  limit: '1mb'
}));

app.post('/api', (request, response) => {
  console.log('I got a request') //Prints I got a request
  console.log(request.body); //Prints {} (empty object)
});

//frontend
function proccessContactMessage() {
  firstName = document.getElementById('contactUsFirstName').value
  lastName = document.getElementById('contactUsLastName').value
  email = document.getElementById('contactUsEmail').value
  message = document.getElementById('contactUsMessage').value

  const data = {
    firstName,
    lastName,
    email,
    message
  };
  const options = {
    method: 'POST',
    mode: 'no-cors',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  };
  fetch('http://localhost:3000/api', options);
}
<form class="formContactUs">
  <div class="contactUsTitleCon">
    <h2 class="contactUsTitle">Contact Us</h2>
  </div>
  <div class="form-group">
    <label for="contactUsFirstName">First Name</label>
    <input type="text" class="form-control" id="contactUsFirstName" placeholder="Enter First Name" required>
  </div>
  <div class="form-group">
    <label for="contactUsLastName">Last Name</label>
    <input type="text" class="form-control" id="contactUsLastName" placeholder="Enter Last Name" required>
  </div>
  <div class="form-group">
    <label for="contactUsEmail">Email</label>
    <input type="email" class="form-control" id="contactUsEmail" placeholder="Enter Email" required>
  </div>
  <div class="form-group">
    <label for="contactUsMessage">Message</label>
    <textarea class="form-control" id="contactUsMessage" placeholder="Enter Message" required></textarea>
  </div>
  <div class="contactUsSubmitBtnCon"><button type="submit" class="btn btn-primary contactUsSubmitBtn" onclick="proccessContactMessage()">Submit</button></div>
</form>

Upvotes: 1

Views: 2019

Answers (5)

Ahmad MOUSSA
Ahmad MOUSSA

Reputation: 2906

I guess, you need a body parser ! You can use the body-parser or the express.urlencoded().

Try this:

In your app.js:

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));// we need to register a parser, to parse the incoming request body !

Or, you can replace that with:

app.use(express.urlencoded({ extended: true })); //Parse URL-encoded bodies

Then, you can do:

console.log(req.body);

Upvotes: 0

Ahmad MOUSSA
Ahmad MOUSSA

Reputation: 2906

As I can understand from our exchange of comments in my first answer, the problem comes from the CORS. If so, try this:

const cors = require('cors');

const corsOptions = {
  origin: (origin, callback) => {
    callback(null, true);
  },
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  allowedHeaders: ["Access-Control-Allow-Origin", "Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"],
  credentials: true
};

app.options('*', cors(corsOptions));
app.use(cors(corsOptions));

Upvotes: 1

chrwahl
chrwahl

Reputation: 13050

In the function proccessContactMessage() you defined data as:

  const data = {
    firstName,
    lastName,
    email,
    message
  };

But this is not a valid JSON object.

//frontend
function proccessContactMessage() {
  firstName = document.getElementById('contactUsFirstName').value
  lastName = document.getElementById('contactUsLastName').value
  email = document.getElementById('contactUsEmail').value
  message = document.getElementById('contactUsMessage').value

  const data = {
    firstName: firstName,
    lastName: lastName,
    email: email,
    message: message
  };

  console.log(data);
  const options = {
    method: 'POST',
    mode: 'no-cors',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  };
  fetch('http://localhost:3000/api', options);
}
<form class="formContactUs">
  <div class="contactUsTitleCon">
    <h2 class="contactUsTitle">Contact Us</h2>
  </div>
  <div class="form-group">
    <label for="contactUsFirstName">First Name</label>
    <input type="text" class="form-control" id="contactUsFirstName" placeholder="Enter First Name" required>
  </div>
  <div class="form-group">
    <label for="contactUsLastName">Last Name</label>
    <input type="text" class="form-control" id="contactUsLastName" placeholder="Enter Last Name" required>
  </div>
  <div class="form-group">
    <label for="contactUsEmail">Email</label>
    <input type="email" class="form-control" id="contactUsEmail" placeholder="Enter Email" required>
  </div>
  <div class="form-group">
    <label for="contactUsMessage">Message</label>
    <textarea class="form-control" id="contactUsMessage" placeholder="Enter Message" required></textarea>
  </div>
  <div class="contactUsSubmitBtnCon"><button type="submit" class="btn btn-primary contactUsSubmitBtn" onclick="proccessContactMessage()">Submit</button></div>
</form>

Upvotes: 0

zx01
zx01

Reputation: 571

Remove mode: 'no-cors' from the options.

This should give you the desired result.

Upvotes: 3

Related Questions