1

I have got an unexpected behavior from my Javascript code. I'm creating a line of table with document.createElement("tr") and an array of cells with that code: cellule = new Array(3).fill(document.createElement("td"));

But when I'm filling it with my values using innerHTML property case by case, the whole array is modified. Here is full code:

ligne = document.createElement("tr");;
cellule = new Array(3).fill(document.createElement("td"));

cellule[0].innerHTML = "Chat";
cellule[1].innerHTML = "Chien";
cellule[2].innerHTML = "Alligator";

ligne.appendChild(cellule[0]);
ligne.appendChild(cellule[1]);
ligne.appendChild(cellule[2]);
maTable.appendChild(ligne);

Results are :

cellule[0] => "Alligator"
cellule[1] => "Alligator"
cellule[2] => "Alligator"

Why is my whole array filled with the last innerHTML used?

4
  • 1
    Because you only have one single td element here. You stuffed three references to the element into your array, but it is still only one element. Commented Apr 3, 2019 at 7:42
  • new Array(3).fill(document.createElement("td")); you add a single <td> element in three different positions in one array. Commented Apr 3, 2019 at 7:43
  • @VLAZ ooh, interristing, should I loop on my array to fill it case by case? Commented Apr 3, 2019 at 7:47
  • I did filling it by looping on it and it works, thanks for your help! Commented Apr 3, 2019 at 7:49

4 Answers 4

1

Because 'filll' was used, the same td was copied, causing an issue. One way is to create an independent td.

ligne = document.createElement("tr");
var datas = ['Chat', 'Chien', 'Alligator'];
for(var i=0; i<datas.length; i++) {
    var td = document.createElement("td");
    td.innerHTML = datas[i];
    ligne.appendChild(td);
}

maTable.appendChild(ligne);
Sign up to request clarification or add additional context in comments.

1 Comment

Hey HolyMoly, thanks for your answer. Please make sure that you explain why this is working compared to his solution. The fact that he has been hardcoding it has nothing to do with the actual problem. The fact that you are creating a new TD for each "data" is.
1

Your issue is with:

cellule = new Array(3).fill(document.createElement("td"));

Here you are creating an array with 3 of the same td elements. So when you change the one at index 0, you are also changing the one at index 1 and 2 as you are referencing the same element in memory.

An easy way to fix this is to manually create an array using a for loop and pushing unique references of the element into your cellule array.

See example below:

var maTable = document.getElementById("myTable");
var ligne = document.createElement("tr");;

var cellule = [];
for(var i = 0; i < 3; i++) {
  cellule.push(document.createElement("td"));
}

cellule[0].textContent = "Chat"; // use textContent instead of innerHTML if only adding text
cellule[1].textContent = "Chien";
cellule[2].textContent = "Alligator";

ligne.appendChild(cellule[0]);
ligne.appendChild(cellule[1]);
ligne.appendChild(cellule[2]);
maTable.appendChild(ligne);
<table id="myTable" border="1"></table>

Comments

1

fill add the same element (with the same reference) into your array.

You can put your elements with another way, like

cellule = [];
for (let i = 3; i--;) {
  cellule.push(document.createElement("td"));
}

or

cellule = new Array(3);
for (let i = cellule.length; i--;) {
  cellule[i] = document.createElement("td");
}

2 Comments

This doesn't work - cellule is a sparse array, so .map will skip the empty positions. You end up with an array with 3 empty positions again.
cellule.fill(0).map(() => document.createElement("td"));
0

When fill gets passed an object, it will copy the reference and fill the array with references to that object.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill#Description

Here is one of the way you could achieve the same.

    cellule = new Array(3).fill("")
    cellule.forEach((el,index) => cellule[index] = document.createElement("td"))
    cellule[0].textContent = "Chat"; 
    cellule[1].textContent = "Chien";
    cellule[2].textContent = "Alligator";
    console.log(cellule[0].textContent);
    console.log(cellule[1].textContent);
    console.log(cellule[2].textContent);

Comments

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.