简体   繁体   中英

nodejs problems passing a paramenter to module

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM