Stupid Looping Problem
The default JavaScript object by reference behavior can jump up and cause problems where you don't expect it to, like in this example.
by james young
HTML
<h2>Expected Results</h2>
<em>Formatted for easier reading.</em>
<pre>
{"cards":[
{"tags":{"CardName":"Goldshire Footman","CardTextInHand":"<b>Taunt</b>"}},
{"tags":{"CardName":"Placeholder Card","CardTextInHand":"Battlecry:Someone remembers to publish this card."}}
]}
</pre>
<hr>
<h2>Actual Results</h2>
<pre id="results"></pre>
<hr>
<h2>The Problem</h2>
<div>Why do the Actual Results have the second card listed twice, instead of each card listed once?</div>
<hr>
<h2>The Solution</h2>
<div>
Because JavaScript always does shallow copies by reference and not deep clones.
You can find out more details at the following links:
<ul>
<li><a href="http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object">http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object</a></li>
<li><a href="http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object">http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object</a></li>
</ul>
This being the case, the solution in this example, since there are no functions inside
of temporaryObject, would be to change line 79 from:
<blockquote><pre>json.cards.push(temporaryObject);</pre></blockquote>
to:
<blockquote><pre>json.cards.push(JSON.parse(JSON.stringify(temporaryObject)));</pre></blockquote>
</div>
JavaScript
'use strict';
/*
* `data` originally came from XML, which is why it is formatted the way it currently is.
* The point of this code is to take this JSON created from XML and turn it into a
* more JSON like feed for easier processing.
*
* Compare the Expected Results to `data` to understand why this is desired.
*
* The `data` in this example has been drastically simplified for the purproses of this
* example as well.
*/
var results = document.getElementById('results'),
data = {
"CardDefs": {
"Entity": [
{
"Tag":[
{
"_": "Goldshire Footman",
"$": {"name": "CardName"}
},
{
"_": "<b>Taunt</b>",
"$": {"name": "CardTextInHand"}
}
]
},
{
"Tag": [
{
"_": "Placeholder Card",
"$": {"name": "CardName"}
},
{
"_": "Battlecry:Someone remembers to publish this card.",
"$": {"name": "CardTextInHand"}
}
]
}
]
}
};
function doit(callback) {
var json = {},
temporaryObject = {};
json.cards = [];
/* Loop though each Entity (there are two) */
data.CardDefs.Entity.forEach(function (entity) {
/* Initialize temporaryObject.tags by setting it to be an empty object */
temporaryObject.tags = {};
/* Loop though each Tag (there are two on each Entity) */
entity.Tag.forEach(function (tag) {
/*
* Add a property onto the temporaryObject.tags object named the value
...