Open
Description
If you have an iteration (for:each
) within another iteration:
<template>
<template for:each={children} for:item="child">
<x-row lwc:if={child.renderMe} prop={child} key={child.id}></x-row>
<template lwc:if={child.children} for:each={child.children} for:item="grandchild">
<x-row lwc:if={grandchild.renderMe} prop={grandchild} key={grandchild.id}></x-row>
</template>
</template>
</template>
... and if you have a sufficient number of lwc:if
layers and duplicated key
s between the grandchildren and the children, then you can get a runtime error:
TypeError: Cannot use 'in' operator to search for 'prop' in undefined
Thrown by:
Or:
TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
Thrown by:
One workaround is to put a key
around the inner loop:
<template>
<template for:each={children} for:item="child">
<x-row lwc:if={child.renderMe} prop={child} key={child.id}></x-row>
+ <div key={child.id}>
<template lwc:if={child.children} for:each={child.children} for:item="grandchild">
<x-row lwc:if={grandchild.renderMe} prop={grandchild} key={grandchild.id}></x-row>
</template>
+ </div>
</template>
</template>
Another workaround is to flatten the array. E.g.:
get flattenedArray() {
return this.children.map(child => [child, ...child.children]).flat() // something like this
}
... and then use a single for:each
:
<template for:each={flattenedArray} for:item="child">
<!-- ... --->
</template>
Repro for first error: nolanlawson/lwc-barebone@836362a
Repro for second error: nolanlawson/lwc-barebone@a97223c
Repro steps: pnpm i && pnpm run dev
Activity