Reputation: 35
In the following code pen you can see that I have setup a factory that takes in an array of Objects as data, loops through that data and then add's button's into the page with an onclick event that logs out the data object.
const testData = [{
fruit: 'Banana'
},
{
fruit: 'Apple'
},
{
fruit: 'Pear'
}
];
const scopeCreep = ({
data
}) => {
const outputDiv = document.getElementById('output');
const getID = () => {
return Math.random().toString(36).substring(7);
};
var lastID;
for (let x = 0; x < data.length; x++) {
data[x].ID = getID();
lastID = data[x].ID;
}
//Add a button to the test div
let button = document.createElement('button');
button.innerText = lastID;
button.onclick = () => {
console.log(privateData, lastID);
outputDiv.innerHTML += "Click resulted in: </br>";
outputDiv.innerHTML += "Array data: " + JSON.stringify(data, null, 2) + ", lastID: " + lastID + "</br>";
};
document.body.appendChild(button);
//JSON parse hack
var privateData = JSON.parse(JSON.stringify(data, null, 2));
//Add new IDS and choose a random one to output as selection
return {
privateData,
data
};
};
const tester = () => {
const outputDiv = document.getElementById('output');
var data1 = scopeCreep({
data: testData
});
outputDiv.innerHTML += "1 load: " + JSON.stringify(data1.privateData, null, 2) + " - " + JSON.stringify(data1.data, null, 2) + "</br>";
var data2 = scopeCreep({
data: testData
});
outputDiv.innerHTML += "2 load: " + JSON.stringify(data2.privateData, null, 2) + " - " + JSON.stringify(data2.data, null, 2) + "</br>";
var data3 = scopeCreep({
data: testData
});
outputDiv.innerHTML += "3 load: " + JSON.stringify(data3.privateData, null, 2) + " - " + JSON.stringify(data3.data, null, 2) + "</br>";
};
document.addEventListener("DOMContentLoaded", tester);
<div id="test">
</div>
<div id="output">
</div>
It seems that the data is being overridden with the last loaded data. (I hope that makes sense?)
My question boils down to: Why is this data being changed out of scope & how can I stop it?
Thanks,
Upvotes: 0
Views: 37
Reputation: 35
I am cloning the data in scope using the following, thankfully the data does not contain any functions as the following would not replicate functions.
JSON.parse(JSON.stringify(data));
Upvotes: 0
Reputation: 926
you have to put this line var privateData = JSON.parse(JSON.stringify(data, null, 2));
at the top of the function in order to clone it before modify the original object
Upvotes: 1