I have the following Express 4 code:
'use strict';
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var log = require('npmlog');
var httpStatus = require('http-status-codes');
var config = require('./config');
var routes = require('./routes');
app.use(function (err, req, res, next) {
log.verbose('Express', '%s %s', req.method, req.url); //Never called
next();
});
app.use(function (err, req, res, next) {
if(err) {
res.status(httpStatus.INTERNAL_SERVER_ERROR).send(err.message); //Never called
}
});
app.use(bodyParser.json());
app.use('/api', routes);
mongoose.connect(config.mongoAddress,
{keepAlive: 1, server: {auto_reconnect: true}},
function (err) {
if (err) {
log.error('Mongo', 'Could not connect to mongo database');
throw err;
} else {
log.info('Mongo', 'Successfully established connection to ' + config.mongoAddress);
}
}
);
var server = app.listen(config.port, function () {
log.info('Server', 'Server listening at %s', server.address().port);
});
My route is working fine, however both functions I have before app.use(bodyParser.json()); are never being called (I also tried adding breakpoints, to no avail). I also tried putting those functions AFTER the route is added, which didn't help (but that was expected).
What am I forgetting?
What's happening is this:
You're including your routes BEFORE you define your middleware. What you should be doing is something like this:
var app = express();
// setup all middlewares here
app.use(...);
app.use(...);
// include all routes here
app.use(routera);
app.use(routerb);
Related
I'm trying to write an API using mongoose and mongolab.
Here is my code :
./index.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect('mongodb://user:pass#****.mlab.com:*****/****');
var Bear = require('./app/models/bear');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
router.use(function(req, res, next){
console.log('request called');
next();
});
router.get('/', function(req, res) {
res.json({ message: 'in /' });
});
router.route('/bears')
.post(function(req, res) {
var bear = new Bear();
bear.name = req.body.name;
console.log(bear.name);
bear.save(function(err) {
console.log('in save')
if (err)
res.send(err);
res.json({ message: 'Bear created!' });
});
});
app.use('/api', router);
app.listen(port);
console.log('connected to port ' + port);
and
./app/models/bear.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BearSchema = new Schema({
name: String
});
module.exports = mongoose.model('Bear', BearSchema);
My problem is, when I try the following request :
It doesn't return anything. I tried to console.log something in bear.save but in never goes in.
I don't get what I am doing wrong. Also when I try to connect to my mongolab db from my terminal it works perfectly well.
There's a problem with your index.js. Here, use this code:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test');
var Bear = require('./bear');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
router.use(function (req, res, next) {
console.log('request called');
next();
});
router.get('/', function (req, res) {
res.json({
message: 'in /'
});
});
/*router.route('/bears')*/
router.post('/bears', function (req, res) {
console.log("request: " + JSON.stringify(req.body));
var bear = new Bear();
bear.name = req.body.name;
console.log(bear.name);
bear.save(function (err) {
console.log('in save')
if (err)
res.send(err);
res.json({
message: 'Bear created!'
});
});
});
app.use('/api', router);
app.listen(port);
console.log('connected to port ' + port);
I am currently implementing a server that handles PayPal API calls from client and comunicates with PayPal's services in order to get token and create users in braintree.
The deployment went out well regarding elastic beanstalk. When i call the token method through the router i get the token and a success. The problem stands when i try to create a new braintree customer i get a cryptic 502 error. Any idea why? I am using the standard nginx setup from AIM listening on port 80. This is not a duplicate since the other similar questions did not resolved my issue.
Using nginx 1.8.0
index.js
var express = require('express');
var router = express.Router();
var http = require('http');
var braintree = require('braintree');
var gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: "xxxxxxxxxxxxxxx",
publicKey: "xxxxxxxxxxxxxxx",
privateKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
});
router.get('/', function(req,res) {
res.send('Iam a tree, a brain tree');
});
router.get('/token', function (req, res) {
gateway.clientToken.generate(null, function (error, response) {
res.json(response);
});
});
router.post('/createCustomer', function(req, res) {
var customer = req.body;
console.log(req.body);
gateway.customer.create({
firstName: customer.firstName,
lastName: customer.lastName,
company: customer.company,
email: customer.email,
phone: customer.phone,
fax: customer.fax,
website: customer.website
}, function (err, result) {
res.json(err,result);
});
});
module.exports = router;
main.js
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// 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;
And finally my www file
#!/usr/bin/env node
var debug = require('debug')('test');
var app = require('../main.js');
app.set('port', process.env.PORT || 8081);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
Answering my question since i found the issue of the problem. The root of the problem was in the "/createCustomer", removing err from
res.json(err,result);
and changing it to
res.json(result);
Also i am not creating a customer with options(name, last name) just an empty one. To wrap it up the "/createCustomer" router function looks like this now.
/* Get Creates a new customer with the given params */
router.post('/createCustomer', function(req, res) {
var customer = req.body;
console.log(req.body);
gateway.customer.create({}, function(err, result) {
res.json(result);
});
});
This is a bit strange since the first version of the function was copied from the Braintree documentation about Node server setup. Anyway for the moment this workaround allows to create a customer link it with my current user on a custom Parse server and edit its properties later.
I have an express app and i have added new route:
this is the route:
var router = require('express').Router();
router.post('/',function (req, res, next) {
res.send("Ok");
});
module.exports = router;
now on every request that i make to this post route im getting at the express log:
finalhandler cannot 404 after headers sent
When making calls to DB the finalhandler does send 404 for every requst,
so im guessing that there is some kind of race with my functions and the finalhandler
anyone have anyidea?
UPDATE:
This is the index.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var _ = require('underscore');
var stringUtils = require("underscore.string");
var mongoose = require('mongoose');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());
var middleware = require('./middleware/authentication-middleware');
app.use(middleware.allowCrossDomains);
app.all('*', loginMiddlewareSkip);
var skipAuthPaths = ['/auth/fb', '/auth/login', '/auth/signup', '/auth/forgot', '/auth/reset'];
function loginMiddlewareSkip(req, res, next) {
if (stringUtils.startsWith(req.path, "/auth") || req.path == '/status'){
return next();
}
middleware.ensureAuthenticated(req,res,next);
next();
}
app.use('/passport', require('./routes/passport'));
app.use('/auth', require('./routes/authenticate'));
app.listen(3000, function() {
console.log('Express server listening on port ' + 3000);
});
The file above is the routes/passport, and the auth file is working fine
Ok the problem was with one of my middle wares:
in my loginMiddlewareSkip function i was calling
middleware.ensureAuthenticated(req,res,next) if the path need an authentication, inside that function i was calling next() if authentication is successfull and as you can see i was calling next() again after calling the ensureAuthenticated function.
removing the next() from loginMiddlewareSkip solved the problem
I am trying to post using restler and return the response to client but response never returns .Below is code I am using and response is just hanging
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var rest = require('restler');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = 3001; // can also get it from process.env.PORT
var router = express.Router();
//this is like interceptor for every route to validate all requests, logging for analytics
router.use(function (req, res, next) {
console.log('route intercepted');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function(req, res) {
res.json({ message: "welcome to restful node proxy layer to business processes" });
});
router.route('/someroute').post(function(req, res) {
rest.postJson('http://localhost/api/sg', req.body).on('complete', function(data, response) {
console.log(response);
}
).on('error', function(data, response) {
console.log('error');
});
});
app.use('/api', router); //all routes are prefixed with /api
app.listen(port);
console.log("server is running magic happens from here");
I have created a new Express application. It generated app.js for me and I have then created the following index.js bringing in socket.io:
var app = require('./app');
server=app.listen(3000);
var io = require('socket.io');
var socket = io.listen(server, { log: false });
socket.on('connection', function (client){
console.log('socket connected!');
});
Can anyone advise how I would access socket.io within the routes files?
For reference, the default generated app.js is below:
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// 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;
SocketIO does not work with routes it works with sockets.
That said you might want to use express-io instead as this specially made for this or if you are building a realtime web app then try using sailsjs which already has socketIO integrated to it.
Do this to your main app.js
app = require('express.io')()
app.http().io()
app.listen(7076)
Then on your routes do something like:
app.get('/', function(req, res) {
// Do normal req and res here
// Forward to realtime route
req.io.route('hello')
})
// This realtime route will handle the realtime request
app.io.route('hello', function(req) {
req.io.broadcast('hello visitor');
})
See the express-io documentation here.
Or you can do this if you really want to stick with express + socketio
On your app.js
server = http.createServer(app)
io = require('socket.io').listen(server)
require('.sockets')(io);
Then create a file sockets.js
module.exports = function(io) {
io.sockets.on('connection', function (socket) {
socket.on('captain', function(data) {
console.log(data);
socket.emit('Hello');
});
});
};
You can then call that to your routes/controllers.
The route:
const Router = require('express').Router
const router = new Router();
router.get('/my-route', (req, res, next) => {
console.log(req.app.locals.io) //io object
const io = req.app.locals.io
io.emit('my event', { my: 'data' }) //emit to everyone
res.send("OK")
});
module.exports = router
The main file:
const app = require('express')()
const server = require('http').Server(app);
const io = require('socket.io')(server)
const myroute = require("./route") //route file dir
app.use(myroute);
server.listen(3000, () => {
console.log('¡Usando el puerto 3000!');
});
app.locals.io = io
I think a better way to do it is to attach the Io server to response object In the first middleware .per the way express is designed the Io server will be available to your subsequent routes.
Check this link