Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Aleks Dahlberg
Aleks Dahlberg
19,103 Points

POST request error - TypeError: Cannot read property 'name' of undefined.

I am having some trouble using nodemailer to send email. I am sure I have it all set up correctly.

app.js

/*Application file */
'use strict';

var express = require('express');
var app = express(); //create the Application
var pug = require('pug'); //require pug for templates
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

//require modules
var blog = require('./routes/blog');
var pages = require('./routes/pages');
var tutorials = require('./routes/tutorials');
var home = require('./routes/home');
var contact = require('./routes/contact');
var port = 4000;

app.set('view-engine', 'pug');
app.set('views', __dirname + '/templates');

 //ROUTES//
app.use('/static', express.static(__dirname + '/public'));
app.use('/', home);
app.use('/pages', pages);
app.use('/blog', blog);
app.use('/tutorials', tutorials);
app.use('/', contact);

 //SERVERS//
//listern on port
app.listen(port, function () {
    setInterval(function () {
        console.log('server is running on port: ' + port);
    },10000)
});

contact.js

var express = require('express');
var router = express.Router();
var nodemailer = require("nodemailer");

router.get('/contact', function (req, res) {
    var path = req.path;
    res.locals.path = path;
    res.render('contact.pug');
});

router.post('/contact/send', function (res, req) {
    var transporter = nodemailer.createTransport({
        service: 'Gmail',
        auth: {
            user: 'myemail@gmail.com',
            pass: 'pass'
        }
    });

    var conName = req.body.name;
    var conEmail = req.body.email;
    var conTopic = req.body.topic;
    var conMessage = req.body.message;
    var text = 'New Mail. Name: ' + conName + ' Email: ' + conEmail + ' Topic: ' + conTopic+ ' Message: ' + conMessage;
    var html = '<p>New Mail.</p><ul><li>Name: ' + conName + '</li><li>Email: ' + conEmail + '</li><li>Topic: ' + conTopic + '</li><li>Message: ' + conMessage + '</li></ul>';

    var mailOptions = {
        from: 'No one <noone@email.com',
        to: 'myemail@gmail.com',
        subject: 'Website Submission',
        text: text,
        html: html
    };

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

module.exports = router;

contact.pug

extends ./home-layout.pug
block content
    div.section
        div.container
            div.row.content-container
                div.col.s12.center.heading
                    h4 Contact
                    br
                div.row
                  form(method="post", action="contact/send").col.s12
                    div.row
                        div.input-field.col.s6.form-padding
                            input.validate(name="name", type='text')
                        div.input-field.col.s6.form-padding
                            input#last_name.validate(placeholder='Email', name="email", type='email')
                    div.row
                      div.input-field.col.s6.form-padding
                        input#input_text(placeholder='Topic',type='text', name="topic", length='10')
                    div.row
                      div.input-field.col.s12.form-padding
                        textarea#textarea1.materialize-textarea(placeholder='Message', name="message", length='120')
                    a
                        button(type="submit").waves-effect.waves-light.btn Send
Simon Coates
Simon Coates
28,692 Points

I don't know the frameworks in question but i googled some sample code. You are using res and req in the right order.?Unless the form is messed up, you should expect the name to be present when you call it in setting the conName (assuming this is where the glitch is occurring - which could be confirmed or denied by replacing conName with a fake value).

Aleks Dahlberg
Aleks Dahlberg
19,103 Points

Simon Coates the error is occurring on conName = res.body.name

Simon Coates
Simon Coates
28,692 Points
router.get('/contact', function (req, res) {
    var path = req.path;
    res.locals.path = path;
    res.render('contact.pug');
});

router.post('/contact/send', function (res, req) {

okay, that's what i thought. If you look at the above, you have the req and res variables in different orders in the different functions. This might explain whey there doesn't seem to be a body attribute on req.

1 Answer

Steven Parker
Steven Parker
216,083 Points

In contact.js you have this:

router.post('/contact/send', function (res, req) {

:point_right: But the request (req) should be the first argument:

router.post('/contact/send', function (req, res) {