Search code examples
javascriptjsonnode.jsstringify

JSON.stringify fails on a newly created object (node, javascript)


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);
}

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.