5

i'm using socket.io in my node project and wanted to know how to possibly export the io variable

this is what i have done so far but i get this error: Object #<Object> has no method 'on'

in app.js:

        var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index')(io);
var users = require('./routes/user');

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);

require('./routes/index')(io);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward 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,
            title: 'error'
        });
    });
}

// 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: {},
        title: 'error'
    });
});
/*
io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});
*/

module.exports = app;

in index.js

var io = require('../app');

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

the reason i want export the variable is so that i dont have to define io is index.js like i did in app.js which leads to me basically defining both server and app variable !

I just want to do all my socket.io stuff in the index.js route essentially (except from having to redefine the app, server and io variables in index.js ) !

Hope i have explained my self enough

Thank you !

ipalibowhyte
  • 1,553
  • 2
  • 22
  • 34
  • Am I mistaken, or do you have a circular dependency? [http://selfcontained.us/2012/05/08/node-js-circular-dependencies/](http://selfcontained.us/2012/05/08/node-js-circular-dependencies/) – mattr Nov 04 '14 at 17:54
  • I am using the express framework so i think i do – ipalibowhyte Nov 04 '14 at 18:13
  • i mean app.js requires index.js and index.js requires app.js. Also, it looks like index is required before you had a chance to initialize app. i think this is a chicken-and-egg problem – mattr Nov 04 '14 at 18:18
  • still sort of new to node js. this is how yomean generated the file and really haven't done anything in app.js. how can i solve this please ? – ipalibowhyte Nov 04 '14 at 18:21
  • ok ill add an answer to refactor the code that may band-aid the problem, stay tuned! ;) – mattr Nov 04 '14 at 18:22
  • just to clarify `var routes = require('./routes/index');`...that is the same `index.js` shown, correct? – mattr Nov 04 '14 at 18:24

4 Answers4

14

Your dependencies are not set up correctly. You are executing index.js before io is initialized

var routes = require('./routes/index');
/* index.js starts being executed at this point
 * hence, io is undefined inside index.js
 */

Instead, why don't you try

app.js

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);
module.exports = io;

var routes = require('./routes/index');
var users = require('./routes/user');

index.js

 var io = require('../app');

io.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
    console.log(data);
    });
});
takinola
  • 1,643
  • 1
  • 12
  • 23
1

I think you need to use the sockets.

io.sockets.on('connection', ... ); 
corn3lius
  • 4,857
  • 2
  • 31
  • 36
0

It looks like a circular dependency (app.js requires index.js and index.js requires app.js)

Try this.

change app.js to:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var users = require('./routes/user');

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);

require('./routes/index')(io);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/users', users);

/// catch 404 and forward 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,
      title: 'error'
    });
  });
}

// 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: {},
    title: 'error'
  });
});
/*
 io.on('connection', function (socket) {
 socket.emit('news', { hello: 'world' });
 socket.on('my other event', function (data) {
 console.log(data);
 });
 });
 */

module.exports = app;

change index.js to:

module.exports = function(io){
  io.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
      console.log(data);
    });
  });
}  
mattr
  • 5,458
  • 2
  • 27
  • 22
0

Use "global.io" instead of "var io" in app.js

Prithiviy
  • 1
  • 1