MightyMouse
MightyMouse

Reputation: 13808

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:

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

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

Upvotes: 2

Views: 1823

Answers (2)

user2736012
user2736012

Reputation: 3543

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.

Upvotes: 3

PSL
PSL

Reputation: 123739

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

Upvotes: 2

Related Questions