Express Middleware being executed out of order - javascript

I'm learning about Express middleware. I separated my middleware functions into a simple module. I usually export my modules as an object rather than a function which might be my issue but if so I'd like to know why.. In any case, I'm getting my first middleware function to output before the handler, then the handler, then the first function again. Can someone explain why this is happening?
Here's my main app.js
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var something = require('./something');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(something.firstMiddle);
app.use(something.lastMiddle);
app.get('/', something.middleHandler, function(req,res){
res.render('index', { title: 'Yo Mama!' });
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
and my module something.js
module.exports = {
middleHandler: function(req,res,next){
console.log('In the handler');
next();
},
firstMiddle: function(req, res, next){
console.log("In first middle!");
next();
},
lastMiddle: function(req,res,next){
console.log('Last middleware');
next();
}
};
It's outputting:
Express server listening on port 3000
In first middle!
In the handler
In first middle!

Related

Node.js browser error Cannot GET/

I'm quite new to Node, I've been following a tutorial to build a simple server that serves dynamic pags with some basic routes but keep getting the Error: Cannot GET/ after running node server.js and calling localhost:3300 on the browser. My routes are defined externally and initialized using a routes.initialise() as follows:
//routes.js
var home = require('../controllers/home'),
image = require('../controllers/image'),
express = require('express');
module.exports.initialize = function(app, router) {
//var router = express.Router();
router.get('/', home.index);
router.get('/images/:image_id', image.index);
router.post('/images', image.create);
router.post('/images/:image_id/like', image.like);
router.post('/images/:image_id/comment', image.comment);
app.use('/', router);
};
I've searched far and wide but no solution forthcoming. I'm really frustrated and will need some help here.
I have a server.js that creates the server:
//server.js
var express = require('express'),
config = require('./server/configure'),
app = express();
app.set('port', process.env.PORT || 3300);
app.set('views', __dirname + '/views');
app = config(app);
var server = app.listen(app.get('port'), function() {
console.log('Server up: http://localhost:' + app.get('port'));
});
and a configure.js that configures the server:
//configure.js
var path = require('path'),
routes = require('./routes'),
exphbs = require('express3-handlebars'),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
morgan = require('morgan'),
methodOverride = require('method-override'),
errorHandler = require('errorhandler');
module.exports = function(app) {
app.engine('handlebars', exphbs.create({
defaultLayout: 'main',
layoutsDir: app.get('views') + '/layouts',
partialsDir: [app.get('views') + '/partials']
}).engine);
app.set('view engine', 'handlebars');
app.use(morgan('dev'));
app.use(bodyParser({
uploadDir:path.join(__dirname, 'public/upload/temp')
}));
app.use(methodOverride());
app.use(cookieParser('some-secret-value-here'));
routes.initialize(app, new express.Router());
app.use('/public/', express.static(path.join(__dirname, '../public')));
if ('development' === app.get('env')) {
app.use(errorHandler());
}
return app;
};
also two files, home.js and image.js which are supposed to provide the default routes from configure.js:
//home.js
module.exports = {
index: function(req, res) {
res.send('The home:index controller');
}
};
//image.js
module.exports = {
index: function(req, res) {
res.send('The image:index controller ' + req.params.image_id);
},
create: function(req, res) {
res.send('The image:create POST controller');
},
like: function(req, res) {
res.send('The image:like POST controller');
},
comment: function(req, res) {
res.send('The image:comment POST controller');
}
};
Anytime I try to GET any of the links on the browser it returns the Cannot GET/ error. Any help will be greatly appreciated.
Thank you so much :)
I actually copied your exact code and it worked as you expect, though frankly it's got a bunch of indirection and at least one deprecated module. Maybe you have a PORT environmental variable set, and so the app isn't actually running on 3300?

node.js TypeError: Object has no method get

I'm trying to separate server initiation and other calls from the core file(app.js) but when I try to run it, it issues me error that
http.createServer(app).listen(app.get('port'), function(){
^
TypeError: Object function (){ all code from app.js file }
has no method 'get'
This is app.js file.
/**
* Module dependencies.
*/
module.exports = function(){
var express = require('express');
var routes = require('./routes');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 4000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
return app;
};
and this is server.js file.
var http = require('http'),
app = require('./app');
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
using express#3.4.0
what am I missing OR doing wrong.. please help.
You have no reason to return a function into your app.js file, just return the express object:
var express = require('express');
var app = express();
// ... more variables
// ... the rest of your code
module.exports = app;
Then, the rest of your code into server.js will work fine.
Remember that module.exports works like a "return" into CommonJS (and therefore NodeJS).
See documentation.
You're passing a function to module.exports, so when you require('./app'), you need to call it like a function:
var http = require('http'),
app = require('./app')();
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

Using Socket.io with Node.js, Express and Jade

I have some trouble to use Socket.io even just to test if a client is connected. I've tried many things and I think that my mistake is, maybe, when I do the app.get function. I have also tried to do this in an route js file but it wasn't conclusive neither. So here are my different codes :
App.js
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('mongodb://xxxxx:xxxxx#ds051067.mongolab.com:51067/jdo');
var app = express(),
server = http.createServer(app) ,
io = require('socket.io').listen(server);
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('This is secret'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
io.sockets.on('connection', function (socket) {
console.log('Un client est connecté !');
});
// app.get('/', routes.index);
app.get('/users', user.list);
app.get('/deplacement',routes.deplacement);
app.get('/monCompte', routes.compte);
app.get('/connexion', routes.connexion);
app.get('/', function(req, res) {
res.render('index.jade');
});
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Index.jade
extends layout
block content
script(src="/socket.io/socket.io.js").
var socket = io.connect('http://localhost:3000');
});
PS : Sorry if my english is bad ^^
You can't use inline javascript in the same script tag as an included script.
extends layout
block content
script(src="/socket.io/socket.io.js")
script.
var socket = io.connect('http://localhost:3000');

Error: .get() requires callback functions but got a [object Undefined]

I am new to node & express and I tried different variations and couldn't figure out why. If I map app.get ('/') to just contentHandler then it works fine. But if I map app.get ('/) to contentHandler.displayWelcomePage then I get the above error. Thanks for looking.
Here is my structure:
app.js
routes/index.js
routes/content.js
app.js
var express = require('express')
, app = express()
, routes = require('./routes')
, http = require('http')
, path = require('path')
, mongoose = require ('mongoose')
, db = mongoose.connection
;
db.on ('error', console.error);
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use (app.router);
routes(app, db);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
routes/index.js
var contentHandler = require('./content');
//this is what I need to add, see my notes below var aHandler = new contentHandler();
module.exports = exports = function (app, db) {
console.log ('inside routes/index.js');
app.get ('/', contentHandler.displayWelcomePage);
//instead of using contentHandler, use aHandler.displayWelcomePage
};
routes/content.js
function contentHandler (req, res, db) {
console.log ('Inside contentHandler');
res.render('index', {layout: false, title: "Jade is three."});
this.displayWelcomePage = function (req, res) {
return res.render('index', {layout: false, title: "Welcome to Jade"});
};
};
module.exports = contentHandler;

NodeJS ReferenceError: io is not defined

I'm getting started on node JS and facing an issue with io lib, here the error :
ReferenceError: io is not defined
at exports.index (D:\dev\lib\index.js:9:5)
at callbacks (D:\dev\node_modules\express\lib\router\index.js:164:37)
at param (D:\dev\node_modules\express\lib\router\index.js:138:11)
at pass (D:\dev\node_modules\express\lib\router\index.js:145:5)
at Router._dispatch (D:\dev\node_modules\express\lib\router\index.js:1 73:5)
at Object.router (D:\dev\node_modules\express\lib\router\index.js:33:1 0)
at next (D:\dev\node_modules\express\node_modules\connect\lib\proto.js:190:15)
at Object.methodOverride [as handle] (D:\dev\node_modules\express\node_modules\connect\lib\middleware\methodOverride.js:49:5)
at next (D:\dev\node_modules\express\node_modules\connect\lib\proto.js:190:15)
at Object.urlencoded [as handle] (D:\dev\node_modules\express\node_modules\connect\lib\middleware\urlencoded.js:51:37)
Here is the content of my app.js file :
var express = require('express');
var path = require('path');
var app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
fs = require('fs');
app.set('port', process.env.PORT || 8080); app.set('views',
path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon()); app.use(express.logger('dev'));
app.use(express.json()); app.use(express.urlencoded());
app.use(express.methodOverride()); app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', require('./lib').index);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
my file lib/index.js :
exports.index = function(req, res){
res.render('index');
io.sockets.on('connection', function (socket) {
socket.emit('message', 'welcome');
});
};
Can anyone help me?
You need to pass io to your route:
exports.index = function(io) {
return function(req,res) {
res.render('index');
io.sockets.on('connection', function (socket) {
socket.emit('message', 'welcome');
}
}
}
And then call it as a function in app.get:
app.get('/', require('./lib').index(io));
I'd recommend declaring the require('./lib') part with your other variables. This would allow for code reuse and better readability (which is relative to each person).
var /*other variables*/,
lib = require('./lib');
Then you could just do app.get('/', lib.index(io));
Just a thought.

Categories