SilverCyber
SilverCyber

Reputation: 107

Error while sending mail with Node and Express

I'm trying to send mail on submission of an HTML form using nodemailer. But wheneve I'm pressing submit button it is showing this error...

TypeError: sendMail is not a function
    at C:\Users\user\Desktop\project\Internship designs\notchup\server.js:20:3
    at Layer.handle [as handle_request] (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\layer.js:95:5)
    at C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\index.js:275:10)
    at jsonParser (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\body-parser\lib\types\json.js:101:7)
    at Layer.handle [as handle_request] (C:\Users\user\Desktop\project\Internship designs\notchup\node_modules\express\lib\router\layer.js:95:5)

And I'm only getting a blank mail without any subject and body. I've tried changing the function name so that it might not conflict with the built in function. I've also tried to change it's data type to 'function' from 'const'. But it couldn't help. How can I solve this?

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form class="">
      <input type="text" id="subject" placeholder="Subject"><br>
      <input type="email" id="email" placeholder="Email"><br>
      <textarea name="text" id="text" rows="10" cols="30"></textarea><br>
      <input type="submit" value="Submit">

    </form>

    <!-- JQuery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <!-- CUSTOM script -->
    <script>
        $('form').on('submit', (e) => {
          e.preventDefault();

          const email = $('#email').val().trim();
          const subject = $('#subject').val().trim();
          const text = $('#text').val().trim();

          const data = {
            email,
            subject,
            text
          };

          $.post('/email',data, function() {
            console.log('Server received our data');
          });

        });
    </script>
  </body>
</html>

server.js

const express = require('express');
const sendMail = require('./send-mail');
const app = express();
const path = require('path');

const PORT = 8080;

// Data Parsing
app.use(express.urlencoded({
  extended: false
}));
app.use(express.json());

app.post('/email', (req, res) => {
  // TODO
  // send email here
  const { subject, email, text } = req.body;
  console.log('Data: ', req.body);

  sendMail(email, subject, text, function(err, data) {
    if (err) {
      res.status(500).json({ message: 'Internal Error' });
    } else {
      res.json({ message: 'Email sent!!!' });
    }
  });
  res.json({ message: 'Message received!!!' })
});

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'views', 'index.html'));
});

app.listen(PORT, () => console.log('Server is starting on PORT, ', 8080));

send-mail.js

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: '[email protected]',
    pass: 'my_password'
  }
});

const sendMail = (email, subject, text) => {
  const mailOptions = {
    from: email,
    to: '[email protected]',
    subject: subject,
    text: text
  };

  transporter.sendMail(mailOptions, function(error, info) {
    if(error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
  });
}

module.exports = sendMail();

Upvotes: 0

Views: 670

Answers (3)

Sachin Kumar
Sachin Kumar

Reputation: 3240

In send-mail.js instead of executing the sendMail function just send the reference of the function.

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: '[email protected]',
    pass: 'my_password'
  }
});

const sendMail = (email, subject, text) => {
  const mailOptions = {
    from: email,
    to: '[email protected]',
    subject: subject,
    text: text
  };

  transporter.sendMail(mailOptions, function(error, info) {
    if(error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
  });
}

module.exports = sendMail; // don't sendMail()

Upvotes: 0

Rashomon
Rashomon

Reputation: 6762

You are exporting the return value of sendMail instead of the function itself:

module.exports = sendMail();

Change it to:

module.exports = sendMail;

Upvotes: 0

Quentin
Quentin

Reputation: 944016

The error message says that sendMail is not a function. So you need to look and determine what it is.

You assign it a value here:

const sendMail = require('./send-mail');

So look in that file and see that it exports:

module.exports = sendMail();

To set a value for export you are calling sendMail and assigning its return value.

There's no return statement in it, so it returns undefined.


If you want to export the sendMail function, then export the function itself. Don't append () to call it and get its return value.

Upvotes: 1

Related Questions