NodeList Data is not getting removed

Viewed 165

I have an array object which has 3 objects. I want to remove all the objects except the first one.

Here is my data which I got from XML:

mrArr[0] = <Data>
                <G> "Val" = "5" </G>
           </Data>  
mrArr[1] = <Data>
                <G> "Val" = "6" </G>
           </Data>
mrArr[2] = <Data>
                <G> "Val" = "7" </G>
           </Data>

I have created a loop to try and do this but it is only removing one element. What is wrong with my loop?:

for(var i = 1; i < myArr.length; i++){
    myArr[i].remove();
}

It is removing only one element.

3 Answers

Since you're mutating the array after every iteration, array.length keeps decreasing. Hence, in your example, the loop gets executed only once, thereby removing only one element.

Here's a working example of what you're trying to achieve.

var nodes = document.getElementsByTagName('div');

console.log('Before removal:', nodes);

while (nodes.length > 1) {
  var node = nodes[nodes.length - 1];
  node.parentNode.removeChild(node);
}

console.log('After removal:', nodes);
<div id="div-01">Here is div-01</div>
<div id="div-02">Here is div-02</div>
<div id="div-03">Here is div-03</div>

Array does not have a function remove. You can use Array#splice like myArray.splice(1);

const myArray = [1, 2, 3];
console.log(myArray);

myArray.splice(1);
console.log(myArray);

If you want to remove not the first item, you need to get the index of the searched item and pass into the splice like

const myArray = [1, 2, 3];
const index = myArray.indexOf(2);
myArray.splice(index, 1);

console.log(myArray);

or just use Array#filter and pass the predicate

const myArray = [1, 2, 3];
const filteredArray = myArray.filter(item => item !== 2);

console.log(filteredArray);

A JavaScript NodeList works differently than a JavaScript Array and what you have there is a NodeList. When you delete/remove a node from DOM, it is also removed from any NodeList that retains it. Therefore you need to iterate the .length of your NodeList but you don't want your increment expression to actually increment:

dataNodes = document.getElementsByTagName("Data");
count = 0; // debug
for (i = 0; i < dataNodes.length; i) {
  console.log('Iteration #',++count,':',dataNodes); // debug
  dataNodes[i].parentNode.removeChild(dataNodes[i]);
}
<Data><G>"Val"="5"</G></Data>
<Data><G>"Val"="6"</G></Data>
<Data><G>"Val"="7"</G></Data>

The above snippet's for loop iterates while i < dataNodes.length but doesn't increment i so i for dataNodes.length iterations is always 0. This way it removes index 0 from the dataNodes for every iteration. In the console, you can see by removing the node from DOM you are also removing it from the dataNode NodeList:

Iteration # 1 : (3) [data, data, data]
Iteration # 2 : (2) [data, data]
Iteration # 3 : [data]
Related