Zoltan
Zoltan

Reputation: 165

Node.js module level variables are undefined

I'm having an issue accessing the scope of a module level variable from within a function inside of said module. See below...

var socketio = require('socket.io');
var socket = socketio.listen();

var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');

socket.on('connection', function connection(socket) {

    socket.emit('message', {data:"test1"});  <====THIS WORKS

    socket.on('init', function init(data) {

        socket.emit('message', {data:"test1"});  <====THIS WORKS

        refreshMyCustomModule();
    });

});

var refreshMyCustomModule = function() {

    socket.emit('message', {data:"test1"}); <=====THIS DOESN'T WORK

    myCustomModule.beginSomeAsyncTask(function(data) { <======THIS DOESN'T WORK

         socket.emit('message', {data:"test2"}); <========THIS DOESN'T WORK

    });

};

Looking at the sample above. When I call my refreshMyCustomModule function suddenly socket and myCustomModule become undefined. I've also tried using this as well as setting up a var self = this.

I've written a bunch in javascript on the client but when coding in node.js it seems like scoping is different and I just can't crack this nut.

Upvotes: 1

Views: 1262

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1073968

Note that the socket at the global level of your script and socket within your function connection are two different variables. The one inside your function connection is the argument that was passed into that function from the connection event. The one you're using in refreshMyCustomModule is the global one, the one on which you called listen.

This is clearer if we change their names, since they're different variables:

var socketio = require('socket.io');
var socketUsedForListen = socketio.listen();

var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');

socketUsedForListen.on('connection', function connection(socketFromConnection) {

    socketFromConnection.emit('message', {data:"test1"});

    socketFromConnection.on('init', function init(data) {

        socketFromConnection.emit('message', {data:"test1"});

        refreshMyCustomModule();
    });

});

var refreshMyCustomModule = function() {

    socketUsedForListen.emit('message', {data:"test1"});

    myCustomModule.beginSomeAsyncTask(function(data) {

         socketUsedForListen.emit('message', {data:"test2"});

    });

};

I'm reasonably certain you meant to use socketFromConnection in refreshMyCustomModule, not socketUsedForListen. If so, either move the refreshMyCustomModule into your connection callback, or pass the socket into it as an argument.

Upvotes: 3

chsh
chsh

Reputation: 2394

It's because you're using an async event in socket.on('init') that leads to the scope issue. I believe if you pass in the parameters you want to use from the parent it will work. e.g.:

var socketio = require('socket.io');
var socket = socketio.listen();

var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');

socket.on('connection', function connection(socket) {
    socket.emit('message', {data:"test1"});  <====THIS WORKS

    socket.on('init', function init(data) {

        socket.emit('message', {data:"test1"});  <====THIS WORKS

        refreshMyCustomModule(socket, myCustomModule);
    });

});

var refreshMyCustomModule = function(socket, module) {

    socket.emit('message', {data:"test1"}); <=====THIS DOESN'T WORK

    module.beginSomeAsyncTask(function(data) { <======THIS DOESN'T WORK

         socket.emit('message', {data:"test2"}); <========THIS DOESN'T WORK

    });

};

Upvotes: 1

Related Questions