2

I am trying to follow the instructions given by Patrick Roberts on this page:

How can i export socket.io into other modules in nodejs?

in my consumer.js when I call socket.emit('message') I get an error back: "Cannot read property 'emit' of null"

Why is emit not available to me?

Here is my code: io.js file (in a middleware directory)

var socketIO = require('socket.io');
var io = null;

exports.io = function() {
  return io;
};

exports.initialize = function(server) {
  io = socketIO(server);

  io.on('connection', (socket) => {
    console.log('user connected')

    socket.emit('newMessage');

    socket.on('hello', (msg) => {
      console.log('message: ' + msg);
    });

    socket.on('disconnect', () => {
      console.log('user disconnected');
    });

  });
};

In app.js I am requiring the io file with:

var io = require('./middleware/io').initialize(server);

In my consumer.js I have the following:

var socket = require('../middleware/io').io();

and then from within a function I am calling:

socket.emit('message') 

The emits coming from within the io.js file are working- its the ones I am trying to use in consumer.js that are not.

Community
  • 1
  • 1
dwax
  • 381
  • 7
  • 19

1 Answers1

2

This line of code:

var io = require('./middleware/io').initialize(server);

loads your module, calls the .initialize(server) method on the module and then assigns the return value from .initialize(server) to your io variable. But, your .initialize() method does return anything so therefore, your io variable will be undefined.

You could fix that my adding a return value to the .initialize() method:

exports.initialize = function(server) {
  io = socketIO(server);

  io.on('connection', (socket) => {
    console.log('user connected')

    socket.emit('newMessage');

    socket.on('hello', (msg) => {
      console.log('message: ' + msg);
    });

    socket.on('disconnect', () => {
      console.log('user disconnected');
    });

  });
  // return the socket.io instance so caller can use it
  return io;
};

Or, alternatively, you could change this:

var io = require('./middleware/io').initialize(server);

to this:

var ioModule = require('./middleware/io');
ioModule.initialize(server);
var io = ioModule.io();
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks, I implemented this code however when I call: socket.emit('newMessage') from within consumer.js I am getting an error that Cannot read property 'emit' of null – dwax Mar 21 '17 at 18:11
  • @dwax - I would only be able to help if I could see the exact code you are trying (you could use "edit" to add it to your question). – jfriend00 Mar 21 '17 at 18:13
  • @dwax - It appears you may be confused about the value of `io` and `socket`. They are not the same. – jfriend00 Mar 21 '17 at 18:38
  • Appreciate the help. I uploaded my code to the following public git repo: https://github.com/daniwaxman/stackoverflow what I am trying to do is that when a user hits the GET:/user route we emit a socket event to all clients. – dwax Mar 21 '17 at 19:01
  • @dwax - Not very many people will look through a repository to try to find where you are having a problem. To improve your chances of getting help and to follow the site guidelines here, you should condense down the code that is causing you problems, explain exactly where the problem is and add that to your question. – jfriend00 Mar 21 '17 at 19:04
  • @dwax - And, FYI, you claim the problem is in consumer.js and I can't even find that in your GitHub repository. – jfriend00 Mar 21 '17 at 19:05
  • apologies- renamed the file when I copied it up. I am re-editing the question above. – dwax Mar 21 '17 at 19:17
  • @dwax - There's all sorts of problems with your code. I'd suggest you start by not breaking it up into so many modules. When you get something simple working, then you can worry about splitting into modules. One problem is that you are creating multiple `app` instances from Express and only one is actually associated with your server so your route in `userRoutes.js` won't ever get called. – jfriend00 Mar 21 '17 at 19:18
  • @dwax - Please go read [How do I ask a good question](https://stackoverflow.com/help/how-to-ask) in the help center here because your question is really not following stack overflow guidelines or making it likely that people will be able to help you or want to help you. It shouldn't be this hard for us to find the problem area of your code. You need to make that REALLY easy by including exactly the problem area of code in your question and you will get lots of quick help. – jfriend00 Mar 21 '17 at 19:19
  • I just edited the question with the exact code samples and description of the problem. – dwax Mar 21 '17 at 19:29
  • @dwax - If you call `var socket = require('../middleware/io').io();` before some other code has called `.initialize()`, it will not work because the internal value of `io` will not yet be set. So, it could be a timing issue. Code that has these type of timing vulnerabilities is just not designed properly. You need to be doing basic debugging, inserting `console.log()` statements in your code and/or setting breakpoints in the debugger to track down exactly what you have at each point in your process. This is basic debugging. We can't do it for you. – jfriend00 Mar 21 '17 at 19:39