tear728 tear728 - 3 months ago 23
AngularJS Question

Making Graph in Javascript - Issue

I need some help debugging a problem with a simple graph (data structure, not a chart). I can insert a node, as well as create a path to the next nodes fine; that's not a problem. The problem is when I call

returnGraph
the node at the first index is returned as
[object Object]
, but all the other nodes are returned as they should be. This is being wrriten with AngularJS by the way.

So I looked for a solution and I read in a few places that this has something to do with either the object's built in string method or a conflict between javascript-objects and json-objects. Unfortunately I'm a little lost since I'm not too familiar with Javascript internals.

First off, here is an example JSON object I am using:

//JSON object waiting to be passed to Node()
obj1 = {
id: 6111,
name: "Node1",
stats: {
"speed": 4
},
ranks: 5,
prereq: 0
}


Here is the rest of the code:

//Pass data from the JSON object through the constructor to create a node
function Node(data){

this.name = data.name;
this.stats = data.stats;
this.maxRank = data.ranks;
this.rank = 0;
}

//Return node name
Node.prototype.returnName = function(){
return this.name;
}

//Increase node rank
Node.prototype.increaseRank = function(){
if (this.rank < this.maxRank){
this.rank += 1;
}
console.log(this.rank);
}



//Graph object
function Graph(){
this.edges = []
}

Graph.prototype.returnNeighbors = function(node){
return this.edges[node];
}

Graph.prototype.addNeighbor = function(node1, node2, node3, node4){

// Prints out node1 as an object
console.log(node1); // Prints out node1 as an object
if (node1 == null){
console.log("something went terribly wrong!");
}
else if (node1 != null && node2 == null && node3 == null && node4 == null) {
this.edges.push({[node1]: []});
}
else if (node4 == null){
this.edges.push({[node1]:[node2, node3]})
}
else{
this.edges.push({[node1]: [node2, node3, node4]})
}
}

Graph.prototype.returnGraph = function(){
return JSON.stringify(this.edges, null, 2);
}


// create a node for each JSON object
$scope.node1 = new Node(obj1);
$scope.node2 = new Node(obj2);
$scope.node3 = new Node(obj3);
$scope.node4 = new Node(obj4);


// create graph
var g = new Graph();
g.addNeighbor($scope.node1, $scope.node2, $scope.node3, $scope.node4);
$scope.g = g;

console.log(g.returnGraph());


This is where the problem lies and is what the above statement prints out. Keep in mind this is the
Graph
:

[
{
"[object Object]": [
{
"name": "Node2",
"stats": {
"speed": 4
},
"maxRank": 5,
"rank": 0
},
{
"name": "Node3",
"stats": {
"attack": 4
},
"maxRank": 5,
"rank": 0
},
{
"name": "Node4",
"stats": {
"block": 4
},
"maxRank": 5,
"rank": 0
}
]
}
]


I've tried using
JSON.parse()
but that wasn't working. I also converted the first node into a string with
JSON.stringify()
and then directly input that string data instead of the actual object, which got me closer , yet it was full of escapes (
\\
,
\t
,
\n
). Using regex didn't help clean it up either.

So is there a better way to solve this
[object Object]
problem? I looked through a lot of answers but could not find a solution. Thanks for any help!

Answer

I suggest that you update your addNeighbor() function like this:

Graph.prototype.addNeighbor = function(node1, node2, node3, node4){
    // Prints out node1 as an object
    console.log(node1); // Prints out node1 as an object
    if (node1 == null){
        console.log("something went terribly wrong!");
    }
    else if (node1 != null && node2 == null && node3 == null && node4 == null) {
        this.edges.push({[node1.name]: []});
    }
    else if (node4 == null){
        this.edges.push({[node1.name]:[node2, node3]})
    }
    else{
        this.edges.push({[node1.name]: [node2, node3, node4]})
    }
}

You're pushing a new object into an existing object. The new object has a key defined as node1.name which will give you an actual string value for the key name. Your code was using node1. Javascript will realize that node1 isn't a string so it will automatically convert the object to a string which is where you're getting [object Object] from.