skip to Main Content

When I try to make a POST request using react with express the request stucks in the middleware of the request. For the front end part I’m using CRA of React and express js for the backend.
I’m not sure where is the problem but any advices will be very helpfull.

Backend

server.js


var express = require('express');
var app = express();
var cors = require('cors');
const corsOptions = {
  origin: '*',
  credentials: true,
  optionSuccessStatus: 200,
};

app.use(cors(corsOptions));
app.use("/contact", contact);
app.use("/offer", offer);

app.listen(3015);

index.js

var nodemailer = require('nodemailer');
var cors = require('cors');
const creds = require('../../config');
const app = express();
const corsOptions = {
  origin: '*',
  credentials: true,
  optionSuccessStatus: 200,
};

// Multiple routing
const router1 = express.Router();
const router2 = express.Router();

app.use(cors(corsOptions));
app.use(express.json());
app.use('/contact', router1);
app.use('/offer', router2);
app.set('port', 3015);

var transport = {
  host: 'kelvin.superhosting.bg',
  port: 587,
  auth: {
    user: creds.USER,
    pass: creds.PASS
  }
}
var transporter = nodemailer.createTransport(transport)
transporter.verify((error, success) => {
  if (error) {
    console.log(error);
  } else {
    console.log(success);
    // console.log('Server is ready to take messages');
  }
});

exports.contact = () => {
  router1.post('/contact', (req, res, next) => {
    // console.log('req.body', req.body);
    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} nn message: ${message} `;
    var mail = {
      from: name,
      to: '[email protected]',  // Change to email address that you want to receive messages on
      subject: subject,
      text: content
    }
    transporter.sendMail(mail, (err, data) => {
      if (err) {
        console.log('err', err)
        res.json({
          status: 'fail'
        })
      } else {
        console.log('here');
        res.json({
          status: 'success'
        })
      }
    });
    next();
  });
}

exports.offer = async () => {
  await router2.post('/offer', (req, res, next) => {
    console.log('req.body', req.body);
    var subject = "Hey this is a subject example";
    var mail = {
      to: '[email protected]',  // Change to email address that you want to receive messages on
      subject: subject,
      attachments: [
        {
          filename: `${req.body.attachments[0].filename}`,
          content: `${req.body.attachments[0].content}`,
          encoding: `${req.body.attachments[0].encoding}`,
        },
      ],
    }
    transporter.sendMail(mail, (err, data) => {
      if (err) {
        res.json({
          status: 'fail'
        })
      } else {
        res.json({
          status: 'success'
        })
      }
    });
  });
}

Fronend
index.jsx

async function fetchMessage() {
    const response = await fetch(`http://localhost:3015/contact`, {
      method: "POST",
      body: JSON.stringify(values[0]),
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
    }).then(
      (response) => (response.json())
    ).then((response) => {
      if (response.status === 'success') {
        setValues([]);
        setName('');
        setEmail('');
        setSubject('');
        setMessage('');
        setCaptchaText('');
        onRefresh();
        setMessageOpen(true);
      } else if (response.status === 'fail') {
        console.log("Message failed to send.", response)
      }
    });

    return response;
  }

Also I try a couple of ways to resolve this issue. For example with/without async/await both in the fronend and backend, multiple times I restart the server and also my local machine.

2

Answers


  1. Chosen as BEST ANSWER

    Thank you for your response. But after editing the code with what you purpose the request still stucks. Here is the code I'm using after changes.

    async function fetchMessage() {
        try {
          const response = await fetch(`http://localhost:3015/contact`, {
            method: "POST",
            body: JSON.stringify(values[0]),
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            },
          });
          return response;
        } catch (err) {
          console.log('err', err)
          err.json({
            status: 'fail'
          })
        }
    }
    
    
    exports.contact = () => {
      router1.post('/contact', async (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} nn message: ${message} `;
        var mail = {
          from: name,
          to: '[email protected]',
          subject: subject,
          text: content
        }
    
        try {
          const info = await transporter.sendMail(mail);
          console.log('here');
          res.json({
            status: 'success'
          })
        } catch (err) {
          console.log('err', err)
          res.json({
            status: 'fail'
          })
        }
      });
    }
    

  2. In your controller functions (contact and offer) you’re using nodemailer‘s sendMail with a callback function. That’s why your request is stuck at the backend, you are registering a callback and immediately your code moves to next, so you’re not sending a response to the client.

    You can use sendMail without a callback function, it will return a Promise, await this promise and use it in try/catch block, send success response if the Promise is resolved or send an error if it’s rejected, similar to this,

    try {
    const info = await transporter.sendMail(mail);
    console.log('here');
    res.json({
        status: 'success'
    })} catch (err) {
    console.log('err', err)
    res.json({
        status: 'fail'
    })
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search