2

I have a LWC that includes a table where I am using a for:each directive to iterate over my dataset and create the rows for my table, with each row having the item Id as the unique key:

<table>
  <template for:each={list} for:item={item}>
    <tr key={item.Id}>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
  </template>
</table>

The above worked fine.

I am now trying to use a custom component to replace some of the <td> elements that have special behaviour.

<table>
  <template for:each={list} for:item={item}>
    <tr key={item.Id}>
      <c-my-custom-table-cell></c-my-custom-table-cell>
      <c-my-custom-table-cell></c-my-custom-table-cell>
      <c-my-custom-table-cell></c-my-custom-table-cell>
    </tr>
  </template>
</table>

The issue is, when I add my custom element to replace the td, I get a Missing key for element error message saying that elements inside an iterator need a unique key.

Update

I've tried a simplified version of my custom table cell:

<template>
  <div>TEST</div>
</template>

with css of:

:host {
  display: table-cell;
}

However, I have already applied the key to the tr element. Why am I being asked for it again?

Further Update In order to be able to use my custom table cells, I also needed to create a custom component for the table row:

css:

:host {
  display: table-row;
}

then I could get everything to work together:

<table>
  <template for:each={list} for:item={item}>
    <c-custom-row key={item.Id}>
      <c-custom-cell value={item.Name}></c-custom-cell>
      <c-custom-cell value={item.StartDate__c}></c-custom-cell>
      <c-custom-cell value={item.EndDate__c}></c-custom-cell>
    </c-custom-row>
  </template>
</table>
3
  • you should not have tr as you are already mentioning table-row in CSS. And it should not be table-cell. What you are doing is table-row Aug 9, 2019 at 12:23
  • Hi. Perhaps I haven't made myself clear, but it is the table cell (td) that I wanted to be custom, and not the table row. I will change the above example so that you can see multiple custom table cells in a row.
    – lemming
    Aug 9, 2019 at 12:48
  • pls check my modified answer. pls let me know if it still does not solve Aug 9, 2019 at 12:49

2 Answers 2

4

I've just had similar issue like 30 minutes ago and I found this topic. Basically what you need to do is add

:host {
    display: table-cell;
}

to your child component and remove surrounding <td> if you have one.


Also add key attribute to your c-my-custom-table-cell:

<table>
    <template for:each={list} for:item={item}>
        <c-my-custom-table-cell key={item.Id}></c-my-custom-table-cell>
    </template>
</table>
5
  • Thanks Bartosz. Did you get this to work for you? I've tried this out, and I'm still getting the same error. I'm doing what sfdcfox suggests, adding the css and not including the td.
    – lemming
    Aug 9, 2019 at 12:01
  • Yes I did. Can you paste add your c-my-custom-table-cell code? Aug 9, 2019 at 12:05
  • Thanks. I've tried just the most basic version I could. I've updated my answer to show this.
    – lemming
    Aug 9, 2019 at 12:18
  • I updated my answer. Basically you need to always use key on first element in iteration Aug 9, 2019 at 12:34
  • Thanks Bartosz. It is the table row I am iterating over, though, not the table cell. Your answer helped me to find a solution, though. I have updated my answer.
    – lemming
    Aug 9, 2019 at 12:58
2

Important

You need custom component to act as table-cell only when table is generic component and number of rows is decided at run-time. Or else you can just use the custom component inside td which works absolutely fine.

ADDED BASED ON COMMENTS

If you need each cell to be custom, you just need below in tbody:

<tbody>
            <template for:each={list} for:item="item">
                <tr key={item.Id}>
                    <td>
                        <c-poc-cell cell-value={item.name}></c-poc-cell>
                    </td>
                    <td>
                        <c-poc-cell cell-value={item.type}></c-poc-cell>
                    </td>
                </tr>
            </template>
        </tbody>

and the cell template:

<template> {cellValue} </template>

You need to define @api cellValue in JS


For having custom component act as tr

You should not have tr. here is the example:

parent comp:

<template>
    <div class="slds-theme_default">
        <table>
            <thead>
                <tr>
                    <td> Name </td>
                    <td> Type </td>
                </tr>
            </thead>
            <tbody>
                <template for:each={list} for:item="item">
                    <c-poc-row key={item.Id} rec={item}></c-poc-row>
                </template>
            </tbody>
        </table>
    </div>
</template>

And in JS, the list:

connectedCallback() {
    this.list = [
        { Id: '1', name: 'qwe', type: 't1' },
        { Id: '2', name: 'we', type: 't2' },
        { Id: '3', name: 'rrr', type: 't3' }
    ];
}

Now the tr component:

<template>
    <td>{rec.name}</td>
    <td>{rec.type}</td>
</template>

and its JS:

import { LightningElement, api } from 'lwc';

export default class PocRow extends LightningElement {
    @api rec = {};
}

and its CSS:

:host {
    display: table-row;
}

Here is the result:

enter image description here

6
  • Thanks, but I am creating a custom table cell, not a custom table row. My understanding from what @sfdcfox said in salesforce.stackexchange.com/questions/251100/… is that I can replace the td if I want.
    – lemming
    Aug 9, 2019 at 12:25
  • Any clue why c-poc-row does need a key? Aug 9, 2019 at 12:32
  • added in answer for custom cell Aug 9, 2019 at 12:33
  • My idea is if not needed for react so should also be not needed in LWC as both are web framework. codepen.io/pranayjaiswal/pen/YmOpjo Aug 9, 2019 at 12:41
  • @PranayJaiswal. template for:each is native to LWC and it does lot of calculations based on key. I checked this in console debug. Aug 9, 2019 at 12:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .