skip to Main Content

Hello guys i’am new to Next.js, before it i used react + express. Now for SEO reasons and to learn too i would like to use Next.js. I’am having problems with the API calls and in the specific with the contact mail. I created a .js in the api folder with 2 functions, the first is the sendMailHandler using nodemailer and the second is the controller with the request. So you send a POST request, i check your data and then call the handler. Now when i fetch the path with this two function, server sends two email, the first is undefined ended by first function and the second is correct with data provided by user. Now the first function is only a function while the second is exported as default. Should i create a folder with this handler function and put only one function in the api route with the handler imported, or there is another way to handle it ?

const nodemailer = require("nodemailer");
import { validEmail } from '../../services';

const contactUsEmail = async (from, subject, tel, text, email) => {

  // create reusable transporter object using the default SMTP transport
  const transporter = nodemailer.createTransport({
    host: 'smtp.ethereal.email',
    port: 587,
    auth: {
      user: '[email protected]',
      pass: 'xxxxxxxxxxxx'
    }
  });

  // send mail with defined transport object
  let info = await transporter.sendMail({
    from: `${email}`, // email address
    to: "[email protected]", // list of receivers
    subject: `${subject}`, // Subject line
    text: `From: ${from}nEmail: ${email}nTel: ${tel}nn${text}`, // plain text body
    // html: "<b>Hello world?</b>", // html body
  });

  console.log("Message sent: %s", info.messageId);
  // Message sent: <[email protected]>

  // Preview only available when sending through an Ethereal account
  console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
  // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
};

contactUsEmail().catch(console.error);

export default async function sendEmailToUs (req, res, next) {
  if(req.method !== 'POST'){
    res.status(400).send('Bad request');
    return
  }

  const email = req.body.email;  

  if(!validEmail(email)){
    res.status(400).send('Errors');
    return
  }else{
    const from = req.body.from;
    const tel = req.body.tel === '' ? '0' : req.body.tel;
    const subject = req.body.subject;
    const text = req.body.text;
    const email = req.body.email;

    contactUsEmail(from, subject, tel, text, email);
    res.status(200).send('Sended');
  }
}

2

Answers


  1. If you have done it this way then it should work as expected:

    const sendEmail = async (to, message) => {
      console.log(to, message);
    };
    
    export default async (req, res) => {
      if (req.method === "POST") {
        // Send your email
        const { to, message } = req.body;
        await sendEmail(to, message);
        res.send({ message: "Sent" });
      } else {
        res.send({ error: "Only POST requests are allowed" });
      }
    };
    
    Login or Signup to reply.
  2. You should not be calling contactUsEmail outside the default export, that’s why it’s trying to send an email twice.

    Remove the following line:

    contactUsEmail().catch(console.error)
    

    Then in your default export add a try/catch block around the contactUsEmail call to handle potential errors.

    export default async function sendEmailToUs (req, res, next) {
        // Remaining code...
    
        try {
            await contactUsEmail(from, subject, tel, text, email);
            res.status(200).send('Sent');
        } catch(err) {
            // Handle error here
            console.error(err);
            res.status(500).send('Errors');
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search