Jason Byron Beedle
Jason Byron Beedle

Reputation: 73

ERR EMPTY RESPONSE

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: '[email protected]',
    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

Upvotes: 0

Views: 1062

Answers (2)

kg99
kg99

Reputation: 766

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;

Upvotes: 1

Vijay122
Vijay122

Reputation: 964

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.

Upvotes: 1

Related Questions