I'm trying to do a single loop and update an object property with each loop value but something unexpected happens:
The first console.log prints the day object property updated as expected. The second one, however, which prints the full object, shows the day property with the value of the final forEach value.
Example:
data.days = [ 5, 6 ]
First loop prints:
newData.date: 5
{prop1: x, prop2: x...., date: 6}
Second loop prints:
newData.date: 6
{prop1: x, prop2: x...., date: 6}
This is the my code:
data.days.forEach(day => {
let newData;
newData = data.data;
newData.date = day;
console.log('newData.date: ' + newData.date)
console.log(newData)
})
I've tried to create the newData variable out of forEach or a for loop instead, but I have the same result.
The issue you are seeing is caused by the fact that the browser console, in an attempt to be very helpful, is not logging a string when you log an object. Instead, it's logging a live view of that object. Therefore, if you log the object and then update it, you will see the updated version in the console. However, when you log the property of the object, the console logs it as a static string.
You can see this here:

The string is just logged as a static string, but the object is treated specially, with syntax highlighting and expanding property views and such.
Here's an example where we log the static stringified version of the object instead as well as the dynamic reference to the object:
let days = [5, 6];
let newData = {};
days.forEach(day => {
newData.date = day;
console.log('newData.date: ' + newData.date);
console.log(JSON.stringify(newData));
console.log(newData);
});
This yields:

Your issue is here:
...
let newData;
newData = data.data;
...
You're not creating a new object with newData variable, instead you're just referencing the same data.data object into it on each iteration. This is why the final newData value will always be what is sets on the last loop iteration.
If want a new distinct object for each loop, you need to (deep) clone/ copy the data.data instead of just referencing it:
var data = {};
data.data = { prop1: 'x', prop2: 'x' };
data.days = [ 5, 6 ];
data.days.forEach(day => {
let newData;
newData = Object.assign({}, data.data);
newData.date = day;
console.log('newData.date: ' + newData.date)
console.log(newData)
});
Note: Object.assign does shallow copy of an object, you need to resort to something else if need to deep copy the object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With