Frage

I have nodejs app using socket io. All event listener I would store in ./config/routes.js

module.exports.routes = {
  '/auth/login': {
    controller: 'auth',
    action: 'login'
  },
  '/user/register': {
    controller: 'user',
    action: 'register'
  },
  '/auth/logout': {
    controller: 'auth',
    action: 'logout'
  }
};

Main app like this:

var router = require('./config/routes.js');
var io = require('socket.io').listen(8888);
// Socket events
io.sockets.on('connection', function(socket) {
  for (var route in router.routes) {
    if (router.routes.hasOwnProperty(route)) {
      socket.on(route, function(data) {
        // Do callback
      });
    }
  }
});

The code did not work, and just the last route callback was call. My question is: how to make that work? thanks

War es hilfreich?

Lösung

Your code registers event listener for all the given routes but when the callback is called the route variable is already set to last because the for loop has already finished executing, so you will be thinking that it only works for the last value. Basically what you need is to trap the route variable, in a way that it is the same for each of the given route handler. This problem and it's solutions are described more in here: JavaScript closure inside loops – simple practical example

Do one of the following:

Use Object.keys and forEach loop. This might be the cleanest solution in here:

Object.keys(router.routes).forEach(function (route) {
  socket.on(route, function(data) {
  });
})

or wrap your code in a immediately called function.

for (var route in router.routes) {
  if (router.routes.hasOwnProperty(route)) {
    (function (route) {
      socket.on(route, function(data) {
      });
    })(route);
  }
}

Or bind route to this variable:

for (var route in router.routes) {
  if (router.routes.hasOwnProperty(route)) {
    socket.on(route, function(data) {
      var route = this;
    }.bind(route));
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top