scottcorgan
scottcorgan

Reputation: 11

Socket.io and Express getting an error "has no method socket"

Here is the error I'm getting when trying to test a basic Socket.io and Express set up (per the example on the socket.io website):

/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:659

        var socket = this.namespaces[i].socket(data.id, true);



 ^

TypeError: Object function extend(another) {
  var properties = Object.keys(another);
  var object = this;
  properties.forEach(function (property) {
    object[property] = another[property];
  });
  return object;
} has no method 'socket'
    at Manager.handleClient (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:659:41)
    at Manager.handleUpgrade (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:588:8)
    at HTTPServer.<anonymous> (/Users/scottcorgan/Projects/sevenly/campaigns/node_modules/socket.io/lib/manager.js:119:10)
    at HTTPServer.emit (events.js:88:20)
    at Socket.<anonymous> (http.js:1390:14)
    at TCP.onread (net.js:334:27)

Appreciate any help I can get, please :)

Upvotes: 1

Views: 1039

Answers (2)

Yaniv Kessler
Yaniv Kessler

Reputation: 878

This problem stems from the fact that you or a library you use are adding functions to Object.prototype.

Thus this code:

Object.prototype.foo = function() {};
Object.prototype.bar = function() {};

var myObj = { x: 1 };

for (var i in myObj) {
   console.log(i)
}

will print: x, foo, bar (not necessarily in that order) and not just x as you expect.

In your case this happens in manager.js:

// initialize the socket for all namespaces
for (var i in this.namespaces) {
    var socket = this.namespaces[i].socket(data.id, true);

    // echo back connect packet and fire connection event
    if (i === '') {
        this.namespaces[i].handlePacket(data.id, { type: 'connect' });
    }
}

This code doesn't expect to encounter the declared: extend key, as you can see from the stack trace of the error:

TypeError: Object function extend(another) {
  var properties = Object.keys(another);
  var object = this;
  properties.forEach(function (property) {
    object[property] = another[property];
  });
  return object;
} has no method 'socket'

the program is actually tried to invoke socket() on the extend function.

See Bob's rant here about adding functions to Object.prototype.

As for the solution, you can either add a conditional statement inside manager.js like so:

// initialize the socket for all namespaces
for (var i in this.namespaces) {
    if ('extend' == i) continue;  // ADDED
    var socket = this.namespaces[i].socket(data.id, true);

    // echo back connect packet and fire connection event
    if (i === '') {
        this.namespaces[i].handlePacket(data.id, { type: 'connect' });
    }
}

or you can remove the Object.prototype.extend = function(...) {} declaration, which is my personal preference.

Upvotes: 1

EhevuTov
EhevuTov

Reputation: 20463

Your this.namespaces[i].socket(data.id, true); does not exist. Do something like console.log(typeof this.namespaces[i].socket(data.id, true)); You'll probably get an undefined

I bet one of the elements of your namespaces array is missing.

Upvotes: 0

Related Questions