Cannot read properties of undefined (reading 'size')

Issue

I have 2 arrays. I’m using a for loop on arr1 and checking if arr2 contains some of the same shoe sizes as in arr1. If the condition checks that a shoe size from arr1 does not exist in arr2, then it will push an object ({size: '-'}) to the newArr, if it does exist it will just push the shoe object from arr2 into newArr

code:

const newArr = []
    const arr1 = [
        { size: 'US 3' },
        { size: 'US 4' },
        { size: 'US 5' },
        { size: 'US 6' },
        { size: 'US 7' },
        { size: 'US 8' },
        { size: 'US 9' },
        { size: 'US 10' },
        { size: 'US 11' },
        { size: 'US 12' },
        { size: 'US 13' },
        { size: 'US 14' },
        { size: 'US 15' },
        { size: 'US 16' }
    ]
    const arr2 = [
        { size: '4', cost: '170' },
        { size: '6', cost: '75' },
        { size: '7', cost: '75' },
        { size: '8', cost: '78' },
        { size: '9', cost: '80' },
        { size: '10', cost: '85' },
        { size: '11', cost: '73' },
        { size: '12', cost: '77' },
        { size: '14', cost: '100' }
    ]

     for (const arr1Item in arr1) {
         let arr1Size = arr1[arr1Item].size
         let includes = arr1Size.includes(arr2[arr1Item].size);
    
         if(includes) {
           newArr.push(arr2[arr1Item])
         } else {
           newArr.push({size: '-'})
         }
      }
 
 console.log(newArr)

The problem is whenever I run this I get this error: TypeError: Cannot read properties of undefined (reading 'size')

This error is happening because of this code here:

arr2[arr1Item].size

The thing I’m confused about is if I console.log(arr2[arr1Item]) INSIDE the for loop, it returns each object from arr2 with no error, only gives an error when I add .size.

I’ve been stuck on this for a bit, would appreciate any help. Thank you.

Solution

You iterate over arr1 using the index variable arr1Item, but then use that to index into arr2. As arr1 has more elements than arr2, you end up trying to accessarr2[9] === undefined and undefined does not have a size attribute hence the error TypeError: Cannot read properties of undefined (reading 'size').

Couple of other problems

  1. newArr is not a const.

  2. Array.protoype.includes() is used to see if, say, 4 of arr2.size matches arr.size like US 4 but this will also incorrectly (substring) match US 14.

Potential solution

Using the fact that both arr1 & arr2 are sorted by the (normalized) size attribute, and that the set of (normalized) arr2.size is a subset of (normalized) arr1.size you can do the transformation in linear time (O(arr1.length)):

const arr1 = [
    { size: 'US 3' },
    { size: 'US 4' },
    { size: 'US 5' },
    { size: 'US 6' },
    { size: 'US 7' },
    { size: 'US 8' },
    { size: 'US 9' },
    { size: 'US 10' },
    { size: 'US 11' },
    { size: 'US 12' },
    { size: 'US 13' },
    { size: 'US 14' },
    { size: 'US 15' },
    { size: 'US 16' }
]
const arr2 = [
    { size: '4', cost: '170' },
    { size: '6', cost: '75' },
    { size: '7', cost: '75' },
    { size: '8', cost: '78' },
    { size: '9', cost: '80' },
    { size: '10', cost: '85' },
    { size: '11', cost: '73' },
    { size: '12', cost: '77' },
    { size: '14', cost: '100' }
]

let newArr = []
for(let i1 = 0, i2 = 0; i1 < arr1.length; i1++) {
        if(i2 < arr2.length && arr1[i1].size.substr(3) === arr2[i2].size) {
                newArr.push(arr2[i2]);
                i2++;
        } else {
                newArr.push({size: '-'});
        }
}
console.log(newArr)

Answered By – Allan Wind

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published