Why do I get & ldquo; Uncaught TypeError: Unable to read the 'length' of undefined (...) & rdquo;?

advertisements

Error Message: Uncaught TypeError: Cannot read property 'length' of undefined(…)

Line 44, Column 23

I have read every post I can find related to this error but have not found anything applicable to this situation.

I'm trying to take a string and turn it into an array of arrays that is formatted to take the shape of steps (codewars' kata); one word across, next word down and so on. The problem I'm running into is that I keep getting an Uncaught TypeError: Cannot read property 'length' of undefined(…) when trying to use the length of an array element within a for loop. So in this nested loop:

for(var i = 0; i < masterStringOdd.length; i++){
    temp2 = proArr.slice(0);
    start2 = even[i].length - 1;
    for(let j = 0; j < odd[i].length; j++){
        let replace2 = masterStringOdd.charAt(i);
        Array.prototype.splice.apply(temp2, [start2, 1].concat(replace2));
        finalOdd.push(temp2);
    }
    start2 += even[i+1].length - 1;
}

With the last line "start2 += even[i+1].length - 1;" (I have tried about a thousand different various of this) I get the error, but if I return that line "return even[i+1].length - 1;" I get 5, which is the correct length. My complete code is at the end of this email if anyone wants to look at it, and believe me I understand it is ridiculous and awkward (working code and completely unpolished) - skills at hand and all that.

Just can't figure out why I can't get and use the value of the element's length in this case. Any help would be greatly, greatly appreciated.

function wordStep(str) {
    let array = str.split(" ");
    let even = [], odd = [], proArr = [], finalEven = [], finalOdd = [];
    //for loop to create sperate arrays for across and down
    for (let i = 0; i < array.length; i++){
        if (i%2 === 0){
            even.push(array[i]);
        } else {
            odd.push(array[i].slice(1,-1));
        }
    }
    //data collection and tool variables, might delete them if the are not    needed
    let finalLength = even.join("").toString().length - (even.length - 1);
    let masterStringEven = even.join("").toString();
    let yAxis = odd.join("").toString().length;
    let masterStringOdd = odd.join("").toString();
    //for loop to create protype array
    for (let i = 0; i < finalLength; i++){
        proArr.push(",");
    }
    // for loop to create final evens arrays
    let start = 0;
    for(let i = 0; i < even.length; i++){
        let temp1 = proArr.slice(0);
        let replace = even[i].split("");
        Array.prototype.splice.apply(temp1, [start, replace.length].concat(replace));
        finalEven.push(temp1);
        start += replace.length-1;;
    }
    // nested loops for final odds' array
    let temp2 = []
    let start2 = 0;

    for(var i = 0; i < masterStringOdd.length; i++){
        temp2 = proArr.slice(0);
        start2 = even[i].length - 1;
        for(let j = 0; j < odd[i].length; j++){
            let replace2 = masterStringOdd.charAt(i);
            Array.prototype.splice.apply(temp2, [start2, 1].concat(replace2));
            finalOdd.push(temp2);
        }
        start2 += even[i+1].length - 1;
    }
}


Fundamentally, what's happening is that you're going past the end of the even array, so even[i] gives you undefined, and then you try to read the length of undefined, which causes the error.

And indeed, we can see that in this loop:

for(var i = 0; i < masterStringOdd.length; i++){
    temp2 = proArr.slice(0);
    start2 = even[i].length - 1;
    for(let j = 0; j < odd[i].length; j++){
        let replace2 = masterStringOdd.charAt(i);
        Array.prototype.splice.apply(temp2, [start2, 1].concat(replace2));
        finalOdd.push(temp2);
    }
    start2 += even[i+1].length - 1;
}

...you're assuming that masterStringOdd.length will always be less than even.length. Nothing in the code ensures this, and in fact it will frequently not be true. masterStringOdd.length is the length of the odd array's entries joined together as a string; even.length is the number of even entries. So there are two reasons why even.length may not be at least as big as masterStringOdd.length: 1. The latter is the length of a string, not an array; and 2. The latter relates to odd, not even.