Reputation: 3225
I have a function which get a json as parameter, build another json with some values from given json and return builded json.
function getMyJSON(json) {
var result = {
lastUpdate: "",
legends: null
};
result.legends = (new Array(json.legends.length)).fill({
name: null,
rgb: null,
values: null
});
for (let j = 0; j < json.legends.length; j++) {
result.legends[j].name = json.legends[j].name;
result.legends[j].rgb = json.legends[j].rgb;
result.legends[j].values = (new Array(10)).fill(0);
console.log(result.legends[0].name); //PRINT ONLY FIRST ELEMENT
}
console.log(result.legends);
return result;
}
The problem appear after for loop
is done. All result.legends
have the same value from the last json.legends
Here is how output look:
The legends.name
of first element(result.legends[0].name
) is changed after every loop.
At the end, all legends.name
from result
are equal with the last legends.name
from json
. Why?
I found on google that it is something about variable scope, but I can't figure it out how to do this.
Upvotes: 1
Views: 46
Reputation: 337560
@NinaScholz has described the problem and solved it, however as I mentioned in the comments on the question you can improve and simplify the logic by using map()
:
var obj = {
legends: [{
name: 'foo',
rgb: 'C00'
},{
name: 'bar',
rgb: 'FFF'
},{
name: 'fizz',
rgb: 'CCFFCC'
},{
name: 'buzz',
rgb: '000000'
}]
}
console.log(getMyJSON(obj));
function getMyJSON(o) {
return {
lastUpdate: "",
legends: o.legends.map(function(item) {
return {
name: item.name,
rgb: item.rgb,
values: (new Array(10)).fill(0)
}
})
};
}
Upvotes: 0
Reputation: 386560
You need independent objects inside of the array. Array#fill
takes the same object reference and this leads to the same result in each object.
Instead of this, you could create a new array with Array.from
and map new objects with the second parameter for a callback.
result.legends = Array.from(
{ length: json.legends.length },
_ => ({ name: null, rgb: null, values: null })
);
Upvotes: 2