1

I'm inexperienced in backend and working with Node and trying to set up an $http POST request to send a form to Express. Each time I make the request, my callback data is null. Perhaps my Express routes are not configured correctly? I'm using Angular to communicate with Express/Node to send an email through nodemailer (which I've already properly configured).

Here is my $http POST request:

client/service/emailer/emailer.js

angular.module('public').factory('EmailerService',function($http) {
    return {
            postEmail: function(emailData, callback) {
            console.log('call http with object', emailData);
            $http({
                method: 'POST',
                url: 'http://my-website.com/server/routes/emailer',
                data: emailData,
                headers: { "Content-Type": "application/json" },
                responseType: 'json'
            }).success(function(data, status, headers, config) {
                console.log('success', data, status);
            }).error(function(data, status, headers, config) {
                console.log('error', data, status);
            }).catch(function(error){
                console.log('catch', error);
            });
        }
    };
});

Here is my server side Express configuration:

server/routes/emailer.js

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var logger = require('morgan');

var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(logger('dev'));

app.post('/emailer', function(req,res) {
    // NOTHING LOGS HERE
    console.log(res, req, req.body, res.body);
});

module.exports = app;

Nothing logs to the console here, and the error handling on the $http request returns this:

emailer.js:4 call http with  Object {email: "asdf"}
angular.js:8632 OPTIONS http://matt-mcdaniel.com/server/routes/emailer net::ERR_CONNECTION_TIMED_OUT(anonymous function) @ angular.js:8632sendReq @ angular.js:8426$get.serverRequest @ angular.js:8146deferred.promise.then.wrappedCallback @ angular.js:11682deferred.promise.then.wrappedCallback @ angular.js:11682(anonymous function) @ angular.js:11768$get.Scope.$eval @ angular.js:12811$get.Scope.$digest @ angular.js:12623$get.Scope.$apply @ angular.js:12915(anonymous function) @ angular.js:19264jQuery.event.dispatch @ jquery.js:4676jQuery.event.add.elemData.handle @ jquery.js:4360
emailer.js:14 error null 0
emailer.js:16 catch Object {data: null, status: 0, headers: function, config: Object, statusText: ""}

For good measure, and since I'm new to learning Express, I'll post my server side app.js.

server/app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var compression = require('compression');
var routes = require('./routes/index');
var contact = require('./routes/emailer');

var app = express();

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(compression());
app.use(require('connect-livereload')({
    port: 35729,
    ignore: ['.js']
}));

/** Development Settings */
if (app.get('env') === 'development') {
    // This will change in production since we'll be using the dist folder
    app.use(express.static(path.join(__dirname, '../client')));
    // This covers serving up the index page
    // app.use(express.static(path.join(__dirname, '../client/.tmp')));
    // app.use(express.static(path.join(__dirname, '../client/public')));

    // Error Handling
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

/**
 * Production Settings
 */
if (app.get('env') === 'production') {

    // changes it to use the optimized version for production
    app.use(express.static(path.join(__dirname, '/dist')));

    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: {}
        });
    });

}

module.exports = app;

app.use(function(req, res) {
    res.sendfile(__dirname + '/dist/index.html');
});

Here is my file Structure:

enter image description here

2
  • Could you add the relevant part of your client/app.js which invokes the POST via your EmailService factory? Commented Apr 29, 2015 at 1:56
  • I wasn't aware I needed to add anything to app.js apart from "var contact = require('./routes/emailer');".. I guess I'm not sure how to invoke the POST request on the back end... Commented Apr 29, 2015 at 1:58

1 Answer 1

2

You've definitely got some problems in your emailer.js route. You should only have routing logic there, you shouldn't be recreating your express app. Express gives you a Router object to make this easy. For example, your emailer.js could look like this:

module.exports = express.Router()
    .post('/emailer', function(req,res) {
        console.log(res, req, req.body, res.body);
        res.json({hello:'world'});
    });

And you can map this route in server/app.js like so:

var emailer = require('./routes/emailer');

// ...After all app.use statements, but *before* your error handlers
app.use('/server/routes', emailer);
Sign up to request clarification or add additional context in comments.

2 Comments

data still comes back null. How should I point to this route with my $http call from my service, should I put the entire address like shown above?
Oh, your response type is JSON and my code is simply returning a string. That might be the issue. I'll update my answer. Also, you should be able to use a relative path from your angular code, eg url: '/server/routes/emailer'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.