1

I've been at this for a few days now, and I've seen the questions on stackoverflow and other places, but I am missing something.

Lets say we have the following JSON:

{
  "nodes":[
    {"name":"node1"},
    {"name":"node2"},
    {"name":"node3"},
    {"name":"node4"}
 ],
  "links":[
    {"source":"node1","target":"node2"},
    {"source":"node1","target":"node3"},
    {"source":"node1","target":"node4"}
  ]
}

Why do the following two pieces of code yield the same output in the console, but the second gives me an error (Uncaught TypeError: Cannot read property 'push' of undefined)?

links = links.map(function(l) {
  var sourceNode = nodes.filter(function(n) { return n.name === l.source; })[0];
  var targetNode = nodes.filter(function(n) { return n.name === l.target; })[0];
  return {
    source: sourceNode,
    target: targetNode
  };
});

_

links.forEach(function(link) {
  link.source = {name: link.source};
  link.target = {name: link.target};
});

Console output:

[{"source":{"name":"node1"},"target":{"name":"node2"}},
 {"source":{"name":"node1"},"target":{"name":"node3"}},
 {"source":{"name":"node1"},"target":{"name":"node4"}}]
mosley
  • 13
  • 4
  • When are you getting the error? – Lukasz Wiktor May 16 '16 at 10:27
  • @Lukasz, I get the error immediately. Not sure I understand your question. See the console output for both of these: https://jsfiddle.net/mosley/m3xynk8q/ (no error), and https://jsfiddle.net/mosley/kLubuw70/ (error). – mosley May 16 '16 at 11:24

1 Answers1

0

There is one significant difference between results of the 2 code snippets.

The first one links source and target nodes by reference. They point to the objects in the nodes array.

The second one creates new objects. They have the same names as those in nodes but they are different objects in memory.

D3 force layout requires that links point to nodes by reference or by index in the array. If you specify indices they will by transformed to references anyway:

Note: the values of the source and target attributes may be initially specified as indexes into the nodes array; these will be replaced by references after the call to start.

Lukasz Wiktor
  • 19,644
  • 5
  • 69
  • 82
  • thank you. Can you explain "links ... by reference", or perhaps point me to somewhere I can read up on this? Also, you say "They point to the objects in the nodes array", how do they point, and can I see that they are indeed pointing to an object, perhaps in the Chrome developer tools? – mosley May 16 '16 at 18:45
  • @mosley here is a great explanation of the difference between passing data by reference vs. by value: http://stackoverflow.com/a/430958/853558. You can see if 2 variables are pointing to the same object just by comparing them with `==` or `===`. Check out this code: https://jsfiddle.net/LukaszWiktor/umnk9edm/ – Lukasz Wiktor May 17 '16 at 10:49