The for…in loop in JS is used only to loop through properties of Objects – objects being a specific datatype that Arrays are not.
// Object:
const object = { a: 1, b: 2, c: 3 };
// Array:
const array = [0, 1, 2];
When i’m debugging things like this, the problem is usually that I’m not clear on the actual value or type of the variables. If you have a bug with something like this:
const addNumbers = function(a, b) {
const sum = a + b;
return sum;
}
Then there is almost certainly a problem with my assumptions about what the parameters of that function contain. This is a common complaint of dynamically typed languages, and why typed languages can help – if you try to pass a string to a variable that was initialized as an integer, javascript says OK, other languages will warn you that you’re probably misunderstanding something.
So back to your code. We know we can’t use a for…in loop on an array. There are a few things we can use, but to keep things simple for now we’ll use a standard for loop. That type of loop just gives us an integer that increases by 1 each time around.
for (let i = 0; i < arr.length; i++) {
// i is commonly used for loop variables by convention.
// I think it stands for incrementer
}
There is one thing I didn’t mention – we need to tell the loop when to stop. That’s the middle condition in the for loop parentheses: i < arr.length
. (I read this code in my head as ‘for let i equal zero, while i is less than array dot length, increment i’) arr.length is a property of all array data types in JS, and gives us an integer value for the number of items in the array. Since arrays are 0-indexed in programming, that means that if we have [0, 1, 2]
the length property will be 3. This is a common source of bugs that you should be aware of, and the reason we use <
instead of <=
here. It even has its own wikipedia page
Ok so now we have a for loop that’s giving us the numbers 0, 1, 2... n-1
where n is the length of our input array.
Your use of the push method is correct here, and that’s not a problem. The problem arises from what you’re passing into the push method: result.failure[0]
. This issue is complex and has to do with scope
. I recommend you do some reading until you understand scope better, as it will really help you understand programming best practices and programming in general on a higher level. Simply put, the result
variable is not in the scope of the makeList()
function. This means that if you reference the result
variable, which lies in the global scope, it will have unintended side-effects. A good rule of thumb with functions is to lean towards ‘pure functions’ a.k.a. functions that only operate on their explicit parameters. This makes the code more maintable in the future (note that this isn’t always possible).
Now we do have access to the data inside the result
variable, because it was passed as a parameter when the function was called at the end of the file: const failuresList = makelist(result.failure);
This means that the arr
parameter will contain the array in the failure
property of the result
object.
Now we just have to loop through the arr parameter to access each item indexed in the array:
for (let i = 0; i < arr.length; i++) {
failureItems.push(`<li class="text-warning">${arr[i]}</li>`)
};
Hopefully this helps. Let me know if you have any questions.