Reputation: 183
I am trying to create an object that has no value on it.
for (let i = 0; i < chartyearsale.length; i++) {
var year = chartyearsale[i].year,
grp = chartyearsale[i].family,
qnt = chartyearsale[i].qnt,
qntsk = chartyearsale[i].qntsk,
fat = chartyearsale[i].total;
total[year] = Object.assign({
[grp]: {
val1: (total[year][grp].val1 || 0) + val1,
val2: (total[year][grp].val2 || 0) + val2,
val3: (total[year][grp].val3 || 0) + val3
}
}, total[year]);
}
The values "year, group, value1, value2 and value3" are all defined.
I am getting this response:
Cannot read properties of undefined (reading 'grp')
I believe this should be done differently:
(total[year][grp].val1 || 0)
//should return 0 if undefined, but it breaks the script!
Upvotes: 0
Views: 812
Reputation: 370679
You can't access a nested property that doesn't exist, even if you alternate it with || 0
on the right-hand side:
const obj = {};
// Forbidden:
console.log(obj.foo.bar);
So doing total[year][group].val1
fails, because total
starts out as the empty object. You need
val1: (total[year]?.[group]?.val1 ?? 0) + value1,
for all three values, to make the nested access safe.
A nicer approach would be, if you're creating the object for the first time:
const total = {
[year]: {
[group]: {
val1: value1,
val2: value2,
val3: value3,
}
}
};
If the properties may already exist:
total[year] ??= {};
total[year][group] ??= {};
const totalGroup = total[year][group];
totalGroup.val1 = (totalGroup.val1 ?? 0) + value1;
totalGroup.val2 = (totalGroup.val2 ?? 0) + value2;
totalGroup.val3 = (totalGroup.val3 ?? 0) + value3;
Upvotes: 2