Assigning array values to generated HTML via forEach & for loop

Hi there,

I’m currently working on a small project where I want to firstly target a dynamic number of items and then assign values from an array to custom data attributes, matching the item and array row numbers at all times until the end of the array is reached so that the data will match up.

At the moment I have the targeting of the elements setup, an array and have attempted to loop through the items in the array using both a forEach and a standard for loop but I am hitting the same problem which is that only the values from the last row are being applied. I have figured out that this is because these are the last values assigned to the variables itemNumber and itemColour but I cannot figure out a way to fix it.

The only thing I can think of is to export the variable values somehow to then build out the generated HTML with them, then continue with the loop.

Any thoughts on how best to achieve this please?

Thanks in advance!

Instead of looping through each item, you already know which item you want - it’s the i’th item in the array. (That’s why you checked if i is less than the length of the array - so you know the ith item exists…)

Thanks! Yeah I figured out after posting that all I needed to do was pick out the second item from the selected row in each part of the loop - doh!

1 Like

I might have this wrong, but seeing as you are checking against items length, wouldnt you want to loop through items instead?

Given you cannot break out of a foreach loop early, maybe a standard for loop might be an option.

Also you have ‘i’ in your loop, do you need targetCount?

const targets = document.querySelectorAll('div');

const items = [
    ["123456", "blue"],
    ["234567", "red"],
    ["345678", "yellow"]
]

const createDiv = function(id, code, colour) {
  return `<div id="${id}" data-number="${code}" data-colour="${colour}">+</div>`
}

for (let i = 0, len = items.length; i < len; i++) {
  const target = targets[i]
  const [code, colour] = items[i]
  // if less divs than items break out of the loop
  if (target === undefined) break
  
  target.insertAdjacentHTML('afterbegin', createDiv(i, code, colour))
}

Its been a long day, so if i have this wrong i apologise.

Danger will robinson.

You dont know the number of divs or items - whichever way around you do it, you need to make sure youre not moving outside the index of the array you’re not looping through.

I very much dislike Javascripts handling of array index referencing. The code there will work, but in pretty much every other language will cause problems. So to those that follow, be careful taking that approach to heart.

Sorry maybe I am being dense, but there are two condition checks to prevent that
i < len and if (target === undefined) break.

I guess one alternative would be to lose the check on target and go for this instead.

const len = Math.min(items.length, targets.length)

for (let i = 0; i < len; i++) { ....

Yeah, the general programmer in me absolutely screams at the second one, because you reference a variable beyond the array bounds to set up for that check. Works in Javascript, but EVERYWHERE else, it’s going to bite you.

1 Like