Himmel
Himmel

Reputation: 3709

Angular $http POST gets null from ExpressJS

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

Upvotes: 1

Views: 1601

Answers (1)

Andrew Lavers
Andrew Lavers

Reputation: 8141

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);

Upvotes: 2

Related Questions