Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix TypeError: Cannot read property 'name' from Express Nodemailer

So I do want to say that I've been searching for the answer for this and I've also tried to console.log my req.body post form and I keep getting undefined. So I feel that I'm losing the data from the form I send, I'm not sure what I"m doing wrong. So time to show some code.

As a note: I am using Handlebars for my Express Setup.

app.js

var express    = require('express'),
    exphbr     = require('express3-handlebars'), // "express3-handlebars"
    nodemailer = require('nodemailer'),
    helpers    = require('./lib/helpers'),

    app = express(), handlebars;

// Create `ExpressHandlebars` instance with a default layout.
handlebars = exphbr.create({
    defaultLayout: 'main',
    helpers      : helpers,
    extname      : '.html',

    // Uses multiple partials dirs, templates in "shared/templates/" are shared
    // with the client-side of the app (see below).
    partialsDir: [
        'views/shared/',
        'views/partials/'
    ]
});

// Register `hbs` as our view engine using its bound `engine()` function.
app.engine('html', handlebars.engine);
app.set('view engine', 'html');

require("./routes")(app, express, nodemailer);

app.listen(3000);

routes.js

module.exports = function (app, express, nodemailer) {

    // set up the routes themselves
    app.get('/', function (req, res) {
        res.render('home', {
            title: 'Larry King Orchestra'
        });
    });

    // I cut out a majority of my routes to make this easier to read.

    // SEND EMAIL FROM FORM
    app.post('/', function (req, res) {
        console.log("WTF");
        console.log(req.body.name);
        console.log(req.body.email);

        var mailOpts, smtpTrans;

        //Setup nodemailer transport, I chose gmail. Create an application-specific password to avoid problems.
        smtpTrans = nodemailer.createTransport('SMTP', {
            service: 'Gmail',
            auth: {
                user: "[email protected]",
                pass: "password" 
            }
        });

        //Mail options
        mailOpts = {
            from: req.body.email, //grab form data from the request body object
            to: '[email protected]',
            subject: 'LKO Contact Form',
            html: 'From: ' + req.body.name + ' &lt;' + req.body.email + '&gt; <br>Phone: ' + req.body.tel + '<br>Date of Event: ' + req.body.date + '<br>Location: ' +  req.body.location + '<br>Details &amp; Comments:<br>' + req.body.message + '<br><br><p>Email form provided by <a href="http://www.wavamedia.com/">WavaMedia</a>.'
        };

        smtpTrans.sendMail(mailOpts, function (error, response) {
            //Email not sent
            if (error) {
                res.render('home', { 
                    title: 'Larry King Orchestra', 
                    msg: 'Error occured, message not sent.', 
                    err: true, 
                    page: 'home' 
                });
            }
            //Yay!! Email sent
            else {
                res.render('home', { 
                    title: 'Larry King Orchestra', 
                    msg: 'Message sent! Thank you.', 
                    err: false, 
                    page: 'home'
                });
            }
        });
    });

    // STATIC ROUTE FOR ASSESTS
    app.use(express.static('assests/'));
};

I renamed the handlebars extension to be .html and I have the main layout using partials. SO app.get('/') will show this next file as a partial, and render it on the page.

contact.html

<form class="contact" action="/" method="post">
    <label for="name">Name</label>
    <input type="name" name="name" id="name">

    <label for="email">Your Email (required)</label>
    <input type="email" name="email" id="email">

    <label for="tel">Phone Number</label>
    <input type="tel" name="tel" id="tel">

    <label for="date">Date of Your Event</label>
    <input type="date" name="date" id="date">

    <label for="location">Venue/Location</label>
    <input type="location" name="location" id="location">

    <label for-"message">Details &amp; Comments</label>
    <textarea name="message" id="message" rows="3"></textarea>

    <input type="submit" name="submit" id="submit" value="Send" class="btn btn-default">
</form>

My Error:

TypeError: Cannot read property 'name' of undefined at c:\xampp\htdocs\lko\routes.js:129:26 at callbacks (c:\xampp\htdocs\lko\node_modules\express\lib\router\index.js:164:37) at param (c:\xampp\htdocs\lko\node_modules\express\lib\router\index.js:138:11) at pass (c:\xampp\htdocs\lko\node_modules\express\lib\router\index.js:145:5) at Router._dispatch (c:\xampp\htdocs\lko\node_modules\express\lib\router\index.js:173:5) at Object.router (c:\xampp\htdocs\lko\node_modules\express\lib\router\index.js:33:10) at next (c:\xampp\htdocs\lko\node_modules\express\node_modules\connect\lib\proto.js:193:15) at Object.expressInit [as handle] (c:\xampp\htdocs\lko\node_modules\express\lib\middleware.js:30:5) at next (c:\xampp\htdocs\lko\node_modules\express\node_modules\connect\lib\proto.js:193:15) at Object.query [as handle] (c:\xampp\htdocs\lko\node_modules\express\node_modules\connect\lib\middleware\query.js:45:5)

So I'm not sure where I'm going wrong with the code. I believe the form is sending data to my node app, but where it's going, I'm not sure. I've setup the post method and so far no luck :( I have been trying for a couple days now. I have nodemailer installed as well. I've restarted the server, updated node and npm.

JavaScript Node Guru Masters, only you can show me the light! And thanks for reading though all of this, totally awesome!

like image 267
jemiloii Avatar asked Mar 19 '14 18:03

jemiloii


2 Answers

app.use(express.bodyParser());

add that to your app.js that's what grabs information from the post data form.

like image 155
mrcni Avatar answered Sep 22 '22 00:09

mrcni


You have to require body parser package for this.
At first you have to install it with npm.

$ npm install --save body-parser

Then require that in your js file.

var bodyParser = require('body-parser');

Then add the parser. As you are using html post method it uses urlencoded as encoding type. For that add this line.

var urlencodedParser = bodyParser.urlencoded({ extended: false });

(If you use json you must use bodyParser.json() instead of this)
Now add the parser with the encoding type to app.post method as follows.

app.post('/',urlencodedParser, function (req, res) {
    //your code here
});
like image 45
Lasitha Yapa Avatar answered Sep 20 '22 00:09

Lasitha Yapa