Recently I got a very weird issue with aura:iteration
and don't know how to solve it yet.
If I sort my list of element to ascending order and delete some element from the list then if I try to sort my list of elements once again I got the following error:
rerender threw an error in 'aura:iteration' [Failed to execute 'insertBefore' on 'Node': The new child element contains the parent.] Failing descriptor: {aura:iteration}
I found similar question Problem re-ordering table rows in a Lightning Component but in my case the DOM is clear. Here is the simplified example that reproduces my issue (you can clone it from here sample issue:
<!-- Main.cmp -->
<aura:component>
<aura:attribute name="items" type="List" />
<aura:attribute name="sortAsc" type="Boolean" default="{!false}" />
<aura:handler name="init" value="{!this}" action="{!c.init}" />
<div class="main">
<aura:iteration items="{!v.items}" var="item">
<div>
<c:Child item="{!item}" />
</div>
</aura:iteration>
</div>
<lightning:button label="Sort Items" variant="brand" onclick="{!c.sortItems}" />
<lightning:button label="Delete Item" variant="brand" onclick="{!c.deleteItem}" />
</aura:component>
MainController.js
<!-- MainController.js -->
({
init: function(component, event, helper) {
var items = [
{attr1: 1, attr2: '1', sortAsc: false},
{attr1: 2, attr2: '2', sortAsc: false},
{attr1: 3, attr2: '3', sortAsc: false},
{attr1: 4, attr2: '4', sortAsc: false},
{attr1: 5, attr2: '5', sortAsc: false},
];
component.set('v.items', items);
},
sortItems: function(component, event, helper) {
var items = component.get('v.items');
var sortAsc = !component.get('v.sortAsc');
component.set('v.sortAsc', sortAsc);
items.sort(helper.sortFunction(sortAsc));
component.set('v.items', items);
},
deleteItem: function(component, event, helper) {
var items = component.get('v.items');
items.splice(0, 1);
component.set('v.items', items);
}
});
MainHelper.js
<!-- MainHelper.js -->
({
sortFunction: function(sortAsc, index) {
return function(a,b) {
if ( sortAsc ) {
return a.attr1 - b.attr1;
} else {
return b.attr1 - a.attr1;
}
}
}
});
Child.cmp
<!-- Child.cmp -->
<aura:component>
<aura:attribute name="item" type="Object" />
{!v.item.attr2}
</aura:component>
Test.app
<aura:application extends="force:slds">
<c:Main />
</aura:application>
To reproduce this issue open Test.app click on "Sort Items" button 2 times. Then click on "Delete Item" and after click on "Sort Items" button 2 times again and you'll see the error.
Is it a Lightning Framework bug. Are there any workarounds?