I need the browser to get a response after sending a mail

I am using netlify functions to send an email and it works fine… as in it does send the email. However on the clientside (browser) I can’t get any response. I need a basic response that would allow me to do a if (status==="success") displayMessage() but I can’t seem to get any response on the browser. I get this message Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data However on sending the request via POSTMAN I get a response ‘Email Sent Succesfully’ which is the body part of the callback response.

Here’s the function that I am using at ./netlify/functions/sendMail

const nodemailer = require("nodemailer");

exports.handler = function (event, context, callback) {
  const mailConfig = {
    host: "smtp.mailgun.org",
    port: 465,
    secure: true,
    auth: {
      user: process.env.MAILGUN_USER,
      pass: process.env.MAILGUN_PASSWORD,
    },
  };
  const transporter = nodemailer.createTransport(mailConfig);

  transporter.verify((error, success) => {
    if (error) {
      console.log(error);
    } else {
      console.log("Ready to send emails");
    }
  });

  const messageData = JSON.parse(event.body);

  const { email, name, mobile, message, subject, recipient } = messageData;

  console.log(messageData);

  const mailOptions = {
    from: email,
    to: recipient,
    subject: subject,
    text: message,
  };

  transporter.sendMail(mailOptions, (error, success) => {
    if (error) {
      console.log(error);
      callback(error);
    } else {
      console.log("email sent");
      callback(null, {
        statusCode: 200,
        body: "Email sent successfully",
      });
    }
  });
};


and on the client side I have this

const form = document.querySelector("#message");

const submitMessage = (event) => {
  event.preventDefault();

  const formData = new FormData(form);

  formData.append("recipient", "testing@gmail.com");
  formData.append("subject", "Submission from website");

  const messageData = Object.fromEntries(formData);

  console.log(messageData);

  const url = ".netlify/functions/sendMail";
  const options = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(messageData),
  };

  fetch(url, options)
    .then((response) => response.json())
    .then((data) => console.log(data));
};

form.addEventListener("submit", submitMessage);

in the fetch request, I expected data to give me a response so I could trigger some action to display a success message…

Can someone advise me what I am doing wrong here?

Hi @alimbolar! If your client side code needs to only check if the response was successful, instead of calling response.json() in your client side code, you can check response.ok to see if the response from your function was successful. So your client side code would look something like this:

fetch(url, options).then((response) => {
   if (response.ok) {
      displaySuccess();
   }
});

response.ok will be true for a response with a status code in the range 200-299. You can check the MDN docs for more information on a Response for fetch here.

response.json() is failing on the client because it expects the body of the response to be JSON. In the case of your function, the body is Email sent successfully which is not JSON. You can also validate this by calling JSON.parse("Email sent successfully") in your browser’s console and you would see a similar error. To correctly parse the body of the response from your function, you would need to call response.text() instead of response.json()

2 Likes

Thanks @cmparsons for your quick, clear and concise explanation…:-)… really appreciate it…

So, thanks to you, I realised that the issue was that body needed to be a stringified JSON and so I did this and it’s now perfect…:-)…

     callback(null, {
        statusCode: 200,
        body: JSON.stringify({
          status: "success",
          message: "Email sent successfully",
        }),
      });

I am now able to check the status and the message on the client side using the response.json()

Thanks again…:-)…

1 Like