req.body is undefined after installing express-static-gzip

90 Views Asked by At

I recently added express-static-gzip to my server and have since noticed that my req.body is undefined in my router.post when submitting a form.

Previously it was working without issue but now I am getting a POST 500 internal server error, a Cannot read property "name" of undefined & a Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 error.

here is my form submission:

const handleSubmit = async (e) => {
    
    e.preventDefault();
    setStatus("Sending...");
    const { name, email, message } = e.target.elements;
    let details = {
        name: name.value,
        email: email.value,
        message: message.value,
    };
    console.log(typeof JSON.stringify(details))
    let response = await fetch("/api/v1/mail", {
        method: "POST",
        headers: {
            "Content-Type": "application/json;charset=utf-8"
        },
        body: JSON.stringify(details),
    });
    setStatus("Send Message");
    let result = await response.json();
    alert(result.status);
};

here is my server setup, the route in question is '/api/v1/mail':

const express = require('express')
const path = require('path')
const router = express.Router();
const cors = require("cors");

var expressStaticGzip = require("express-static-gzip")

const mailRoutes = require('./routes/mail');

const server = express()

server.use('/api/v1/mail', mailRoutes)
server.use(cors())
server.use(express.json())
server.use("/", router)
server.use(expressStaticGzip(path.join(__dirname, 'public'), {
  enableBrotli: true
}))

server.use(express.static(path.join(__dirname, 'public')))

and here is my POST request:

       router.post("/", (req, res) => {
  const name = req.body.name;
  const email = req.body.email;
  const orderId = req.body.orderId
  const message = req.body.message; 
  const mail = {
    from: name,
    to: "[email protected] ",
    subject: "Contact Form Submission",
    html: `<p>Name: ${name}</p>
           <p>Email: ${email}</p>
           <p>Order ID: ${orderId}
           <p>Message: ${message}</p>`,
  };
  contactEmail.sendMail(mail, (error) => {
    if (error) {
      res.json({ status: "ERROR" , req});
    } else {
      res.json({ status: "Message Sent" });
    }
  });
});

})
1

There are 1 best solutions below

0
On BEST ANSWER

If the route you're trying to use req.body.name in is this one:

server.use('/api/v1/mail', mailRoutes)

Then, you have to move this:

server.use(express.json())

to be BEFORE that route definition.

As it is, you're trying to handle the route request before your middleware has read and parsed the JSON. Route handlers and middleware are matched and executed in the order they are registered. So, any middleware that needs to execute for a route handler to function must be registered before the route handler itself is registered.