ERR EMPTY RESPONSE

41
November 24, 2020, at 8:20 PM

I am trying to add a contact form that will send to a dedicated gmail account. I have got the contact form working independently but when I try and add it to my working project it does not work and the error I get is:

Cannot POST /api/send

The project is a MERN stack. Below is the mailer.js middleware:

import nodemailer from 'nodemailer'
import config from '../config'
const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 587,
    auth: {
      user: process.env.username,
      pass: process.env.password,
    }
});
const send = ({ email, name, text }) => {
  const from = name && email ? `${name} <${email}>` : `${name || email}`
  const message = {
    from,
    to: 'react.nodemailer@gmail.com',
    subject: `New message from ${from} at creating-contact-forms-with-nodemailer-and-react`,
    text,
    replyTo: from
  };
  return new Promise((resolve, reject) => {
    transporter.sendMail(message, (error, info) =>
      error ? reject(error) : resolve(info)
    )
  })
}
export default send

The server.js on the backend is:

const express = require('express');
const connectDB = require('./config/db');
const path = require('path');
// // ********************
// // CONTACT FORM 
// // ********************
const cors = require ("cors")
const nodemailer = require("nodemailer")
// // ********************
// // CONTACT FORM 
// // ********************

const app = express();
// // Connect Database
connectDB();
// Init Middleware
app.use(express.json());
// // ********************
// // CONTACT FORM 
// // ********************
app.use(cors());
app.post('/contact', (req, res) => {
  const { email = '', name = '', message = '' } = req.body
  mailer({ email, name, text: message }).then(() => {
    console.log(`Sent the message "${message}" from <${name}> ${email}.`);
    res.redirect('/#success');
  }).catch((error) => {
    console.log(`Failed to send the message "${message}" from <${name}> ${email} with the error ${error && error.message}`);
    res.redirect('/#error');
  })
})
// // ********************
// // CONTACT FORM 
// // ********************
// Define Routes
app.use('/api/users', require('./routes/api/users'));
app.use('/api/auth', require('./routes/api/auth'));
app.use('/api/profile', require('./routes/api/profile'));
app.use('/api/posts', require('./routes/api/posts'));
app.use('/api/send', require('./routes/api/send'));

// Serve static assets in production
if (process.env.NODE_ENV === 'production') {
  // Set static folder
  app.use(express.static('client/build'));
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  });
}
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

The contact form is:

import React, { Component } from "react";
import axios from "axios";
class ContactForm extends Component {
  constructor() {
    super();
    this.state = {
      name: "",
      email: "",
      message: "",
      status: "Submit"
    };   
  }
  handleSubmit(event) {
    event.preventDefault();  
    this.setState({ status: "Sending" });  
    axios({
      method: "POST",
      url: "api/send",
      data: this.state,
    }).then((response) => {
      if (response.data.status === "sent") {
        alert("Message Sent");
        this.setState({ name: "", email: "", message: "", status: "Submit" });
      } else if (response.data.status === "failed") {
        alert("Message Failed");
      }
    });
  }
 
  handleChange(event) {
    const field = event.target.id;
    if (field === "name") {
      this.setState({ name: event.target.value });
    } else if (field === "email") {
      this.setState({ email: event.target.value });
    } else if (field === "message") {
      this.setState({ message: event.target.value });
    }
  }

This is the api POST route.

var express = require('express');
var config = require('config');
var router = express.Router();

var cors = require('cors');

// @route   POST api/send
// @desc    Send email on contact page
// @access  Public
router.post('/api/send',(req, res, next ) => {
    var name = req.body.name
    var email = req.body.email
    var subject = req.body.subject
    var message = req.body.message
    var content = `
    name: ${name} \n 
    email: ${email} \n 
    subject: ${subject} \n 
    message: ${message} `
    var post = {
      from: name,
      subject: subject,
      text: content
    }
  });

  module.exports = router;

I have been trying to debug this for a week or so. I am currently trying to find out why the POST route is not working.

The error codes I have got are 500 internal server error and 404 not found. The url it will be going to is http://localhost:5000/api/send

Answer 1

Change

router.post('/api/send',(req, res, next )

to

router.post('/',(req, res, next )

In your express app your already have.

app.use('/api/send', require('./routes/api/send'));

Thus, for all "/api/send" we will look in the file './routes/api/send'.

The way you defined it you will have to query it like http://localhost:5000/api/send/api/send.

You will have

router.post('/',(req, res, next ) => {
    var name = req.body.name
    var email = req.body.email
    var subject = req.body.subject
    var message = req.body.message
    var content = `
    name: ${name} \n 
    email: ${email} \n 
    subject: ${subject} \n 
    message: ${message} `
    var post = {
      from: name,
      subject: subject,
      text: content
    }
  });

  module.exports = router;

Also how about moving routes to its own file. i.e in server have

app.use(require('./routes/api'));

And in ./routes/api/index.js have the definitions there. i.e

const express = require('express');
const router = express.Router();
router.use('/api/send', require('./send'));

module.exports = router;
Answer 2

You can directly register the route on the express app like below,

app.post('/api/send',function(){
//..send code
//nodemailer.send("blabla")
});

instead of registering routes both on app and router.

READ ALSO
How can you not pause the application when errors occur (in the mongoose nodejs express)?

How can you not pause the application when errors occur (in the mongoose nodejs express)?

I use it mongoose nodejs expressWhen a validation error or mongoose error arc occurs, the application stops

55
Node.js fast-csv synchronously read file and return array

Node.js fast-csv synchronously read file and return array

I am trying to read acsv file and to assign it to an array with this code:

35
I want to upload a file to file.cm from telegram

I want to upload a file to file.cm from telegram

I want to upload a file to filecm from telegram, but I could not find any case studies on this topic

36
how do i solve this mistake i&#39;m going crazy

how do i solve this mistake i'm going crazy

enter image description here

46