0

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!
0

1 Answer 1

2

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;
Sign up to request clarification or add additional context in comments.

5 Comments

Its because i dont know how many “year” and “group” are… thats why i cant set previosly
What do you mean, you don't know how many there are? An identifier is a (single) identifier, referring to exactly one value, not multiple. If you have an array of properties to iterate over and insert into the object, use array methods or for..of to iterate over them.
i edited to show all my code, i tried to make the question more simple, now the error is gone but it wont increment with new values, just replaces it
If the properties may already exist, and you're not definitely starting from the empty object, then use the code in the last part of my answer. Your existing approach with the Object.assign does not preserve other groups on the object - it replaces it with an entirely new object.
yeap, (total[year]?.[group]?.val1 ?? 0) approch with pre setting total[year] ??= {}; total[year][group] ??= {}; in the loop seal the deal, you saved my day!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.