5

Working with a prototype of a lightning web component, I get that the datatable, just like its Aura brother, needs the columns to be manually specified.

That being said, I have the following specification for a datatable that receives pricebook entries:

const columns = [
    { label: 'Name', fieldName: 'Product2.Name' }
]

The names do not display on the component, but if I use a forEach to list the data retrieved by the component, I get the products names, like in:

connectedCallback() {
    getProducts({ pricebookId: this.pricebookId, countLimit: 4 })
        .then(result => {
            this.products = result
            this.products.forEach(p => {
                console.log(p.Product2) // Proxy {} object is displayed
                console.log(p.Product2.Name) // The name is displayed
            });
            this.tableIsLoading = false
        })
        .catch(error => {
            console.error(error)
        })
}

If the datatable component does not support this, then the correct way of dealing with this is to work with the retrieved data, and build a new list with direct access to the data (no parent-child objects), or to edit the current data and include fields that I can access?

For example, should I iterate the result data and add a productName attribute to the elements, and then set 'productName' as the attribute on the column variable?

Edit: just noticed that you can't iterate the data list and create a new productName property. You end up with a TypeError: 'set' on proxy: trap returned falsish for property 'productName'.

1 Answer 1

6

The lightning:datatable assumes that the field name is not an object, but you can have a period in a field name.

Consider this data:

[{ 'Product.Name': 'Hello' }, 'Product': { 'Name': 'World' }}]

If you had data like this, the output in lightning:datatable would be "Hello", not "World".

Here's a copy-paste example for you:

<aura:application extends="force:slds">
    <!-- attributes -->
    <aura:attribute name="data" type="List" default="[{'Product.Name':'Hello', 'Product':{'Name':'World'},'id':'5'}]"/>
    <aura:attribute name="columns" type="List" default="[{ 'label':'Product Name','fieldName':'Product.Name'}]" />

    <!-- the container element determine the height of the datatable -->
    <div style="height: 300px">
        <lightning:datatable
                             keyField="id"
                             data="{! v.data }"
                             columns="{! v.columns }"
                             hideCheckboxColumn="true"/>
    </div>

</aura:application>

This is true for both the Aura and Web component versions.

So, to answer your question, yes, you will need to do some post-processing on your data. It can be as simple as:

this.products = result.map(
  record => Object.assign(
    { "Product2.Name": record.Product2.Name },
    record
  )
);
6
  • That doesn't seem to work. I get a TypeError: 'set' on proxy: trap returned falsish for property 'Product2.Name' inside the forEach. Mar 26, 2019 at 22:39
  • @RenatoOliveira My aura demo works correctly; let me set up a lwc real quick, I'll be back.
    – sfdcfox
    Mar 26, 2019 at 22:41
  • 2
    @RenatoOliveira Network issues, but I came up with a working demo for LWC-style JS as well. Let me know if that helps.
    – sfdcfox
    Mar 26, 2019 at 23:14
  • 2
    That worked. That's really nice, using map and assign to avoid the proxy issues. Mar 26, 2019 at 23:17
  • 1
    @RenatoOliveira I am not sure what accepted best practices are, but I too flatten my datatable data. However, I tend to avoid dot notation in flattening just because it's typically associated with JS object properties. You might consider usage of _ in place of .
    – tsalb
    Mar 27, 2019 at 7:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.