Question

Ok, this one has to be a very easy question, but I just started learning node. I am also new to javascript, so, please show no mercy on pointing out wrong directions below.

In particular I have two files:

  • one has a class that creates some slave servers in different ports
  • the other one is the "main" file that generates the slaves

When I attempt to print out what I have just initialized I get two weird errors:

  • connections property is deprecated. Use getConnections() method, and then
  • it crashes when I attempt to apply JSON.stringify in the new object (Converting circular structure to JSON)

Code for slaves in file "slave.js":

var http = require ("http");

function Slave () {
}

Slave.prototype.ID           = undefined;
Slave.prototype.coordinator  = false;
Slave.prototype.httpServer   = undefined;
Slave.prototype.thePort      = undefined;

Slave.prototype.isCoordinator = function () { return this.coordinator; }

/*****************************************************************/

function handle_incoming_request (req, res) {
    console.log("INCOMING REQUEST: " + req.method + " " + req.url);
    res.writeHead (200, { "Content-Type" : "application/json" });
    res.end( JSON.stringify({ "error" : null }) + "\n" );
}

exports.createSlave = function (id, coordinatorK, port) {
    var temp         = new Slave ();
    temp.ID          = id;
    temp.coordinator = coordinatorK;
    temp.thePort     = port;
    temp.httpServer  = http.createServer(handle_incoming_request);
    temp.httpServer.listen (temp.thePort);
    console.log ("Slave (" + (temp.isCoordinator() ? "coordinator" : "regular") + ") with ID " + temp.ID + " is listening to port " + temp.thePort);
    console.log ("--------------------------------------------");

    return temp;
}

Now, the main file.

var http   = require ("http");
var url    = require ("url");
var a      = require ("./slave.js");

var i, temp;
var myArray = new Array ();

for (i = 0; i < 4; i++) {
    var newID = i + 1;
    var newPort = 8000 + i + 1;
    var coordinatorIndicator = false;

    if ((i % 4) == 0) {
        coordinatorIndicator = true; // Say, this is going to be a coordinator
    }

    temp = a.createSlave (newID, coordinatorIndicator, newPort);
    console.log ("New slave is  : " + temp);
    console.log ("Stringified is: " + JSON.stringify(temp));

    myArray.push(temp);
}
Was it helpful?

Solution

You're trying to stringify the result of http.createServer(...). That'll not be what you want to do, so when you create that property, make it non-enumerable by defining it using Object.defineProperty().

exports.createSlave = function (id, coordinatorK, port) {
    var temp         = new Slave ();
    temp.ID          = id;
    temp.coordinator = coordinatorK;
    temp.thePort     = port;

    Object.defineProperty(temp, "httpServer", {
        value: http.createServer(handle_incoming_request),
        enumerable: false, // this is actually the default, so you could remove it
        configurable: true,
        writeable: true
    });
    temp.httpServer.listen (temp.thePort);
    return temp;
}

This way JSON.stringify won't reach that property curing its enumeration of the object.

OTHER TIPS

Issue is the with the property httpServer of temp object having circular reference. You can either set it non enumerable using Ecmascript5 property definision as mentioned in the previous answer or you can use the replacer function of JSON.stringify to customize it not to stringify the httpServer property.

   console.log ("Stringified is: " + JSON.stringify(temp, function(key, value){
         if(key === 'httpServer') return undefined;
        return value;
    }));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top