[SalesForce] Is it not possible to get a parent field in a datatable column specification, for a Lightning Web Component

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'.

Best Answer

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
  )
);