I am having a headache trying to pass a variable to module.
In node.js I have the following distribution:
The node.js server (server.js):
// modules =================================================
var express = require('express');
var app = express();
// configuration ===========================================
app.set('port', process.env.PORT || 3000);
var myRoutes = require('./my.router')(app);
// Start the Server ===========================================
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app; // expose app
The router (my.router.js):
var myCtrl = require('./my.controller');
module.exports = function(app) {
app.get('/api/some', myCtrl.some);
app.get('/api/other', myCtrl.other);
}
The controller(my.controller.js):
exports.some = function(req, res, next) {
res.send('some');
};
exports.other = function(req, res, next) {
res.send('other');
}
This works ok. My problems come when I try to use socket.io and emit an event when /api/some is called.
I need the app object to create the server so I change the router to:
var myCtrl = require('./my.controller');
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
app.get('/api/some', myCtrl.something);
app.get('/api/other', myCtrl.other);
}
And I change the controller to emit the event when /api/some is called:
exports.some = function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
};
exports.other = function(req, res, next) {
res.send('other');
}
Inside the controller I need the io object to make this work.
It may sound simple to someone with a bit more knowledge of node.js but I am not capable of making it work.
I would need something like app.get('/api/some', myCtrl.something(io)) but this is not working...
Can't you just split your code:
var server = require('http').createServer(app);
var io = require('socket.io')(server);
At this stage you have your io, then
var myCtrl = require('./my.controller')(io);
You pass the io as a parameter to your controller which should then be a function like:
/* my.controller.js */
module.exports = function(io) {
some: function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
},
other: function(req, res, next) {
res.send('other');
}
}
Or something along those lines.
// modules =================================================
var express = require('express');
var app = express();
// configuration ===========================================
app.set('port', process.env.PORT || 3000);
var server = require('http').createServer(app);
app.io = require('socket.io')(server); //add io key to app
server.listen(3001);
require('./my.router')(app);
app.Controllers = {};
app.Controllers.myCtrl = require('./my.controller')(app); //pass app to controllers as well (not necessary but you can bootstrap your controllers at the start instead of requiring them in files)
//app.Controllers.anotherCtrl = require('./my.anotherController')(app); //example
// Start the Server ===========================================
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app; // expose app
Controller
module.exports = function(app) {
var Controller = {};
var io = app.io;
Controller.some = function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
};
Controller.other = function(req, res, next) {
res.send('other');
}
return Controller;
};
Route
module.exports = function(app) {
var myCtrl = app.Controllers.myCtrl;
app.get('/api/some', myCtrl.some);
app.get('/api/other', myCtrl.other);
}
You can use the request object to pass the data between different routes.
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
//middleware used to assign 'io' to the request object
function passIoObject(req, res, next) {
req.myIo = io;
next()
}
// either use app.use(passIoObject) if io should be available for all following routes
// or pass it only to specific routes
app.get('/api/some', passIoObject, myCtrl.something);
app.get('/api/other', myCtrl.other);
}
and in your main controller you would access it using:
exports.some = function(req, res, next) {
req.myIo.sockets.emit('my_event', {});
res.send('some');
}
Beside that you should avoid a construct like:
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
app.get('/api/some', myCtrl.something);
app.get('/api/other', myCtrl.other);
}
The larger the code becomes the more problems you will have with maintainability, because you will always need look into the require('./my.router')
file to see which paths/prefix are handled by the code.
Instead write it that way:
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
var router = express.Router();
router.get('/some', myCtrl.something);
router.get('/other', myCtrl.other);
return router;
}
And in server.js
var myRoutes = require('./my.router')(app);
app.use('/api', myRoutes);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.