Flatten data to display it using lightning datatable in LWC

you can prepare data before passing to lightning:datatable

@wire(getAddress, { LeadID: '$recordId' }) wired(result) {
    this.refreshTable = result;
    if (result.data) {
        let preparedAddresses = [];
        result.data.forEach(address => {
            let preparedAddress = {};
            preparedAddress.Account_Id = address.AccountId.Id;
            preparedAddress.Account_Name = address.AccountId.Name;
            preparedAddress.Contact_Id = address.ContactID.Id;
            preparedAddress.Contact_Name = address.ContactID.Name;
            preparedAddress.Contact_Title = address.ContactID.Title;
            // and so on for other fields
            preparedAddresses.push(preparedAddress);
        });
        this.addresses = preparedAddresses;
    }
    if (result.error) {
        this.error = result.error;
    }
}

after that set column with names of fields from preparedAddress

const columns = [
    {
        type: 'action',
        typeAttributes: { rowActions: actions },
    },
    { label: 'Account Id', fieldName: 'Account_Id', type: 'text' },
    { label: 'Account Name', fieldName: 'Account_Name', type: 'text' },
    { label: 'Contact Id', fieldName: 'Contact_Id', type: 'text' },
    { label: 'Contact Name', fieldName: 'Contact_Name', type: 'text' },
    { label: 'Contact Title', fieldName: 'Contact_Title', type: 'text' }
];

You can use this component.

Sample: (Notice how we got CreatedBy.Name below)

<template>
    <c-datatable config={config}>
    </c-datatable>
</template>

and its JS:

import { LightningElement, track } from 'lwc';

export default class PocTable extends LightningElement {
    config = {
        objectName: "Account",
        tableConfig: {
            columns: [
                { api: 'Name', label: 'Name', fieldName: 'Name', sortable: true },
                { api: 'CreatedDate', label: 'Created On', fieldName: 'CreatedDate', type: 'date', sortable: true },
                { api: 'CreatedBy.Name', label: 'Created By', fieldName: 'CreatedByName', sortable: true }
            ]
        }
    };
}

NOTE: You need add api property in columns which will be used to fetch data from database.

More information - lightning datatable (AURA or LWC) can automatically fetch records from database?


You can easily build the flatten model for use with the data table using the javascript function Object.assign() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.

@wire(getProductsWithPriceInfo, {
    opportunityId: "$recordId"
})
getProducts(result) {
    this.wiredProductResult = result;
    this.allProducts = [];

    if (result.data) {
        for (let i = 0; i < result.data.length; i++) {
            let row = result.data[i];
            this.allProducts = [
                ...this.allProducts,
                Object.assign(
                    {
                        ProductName: row.Product2.Name,
                        ProductFamily: row.Product2.Family,
                        ProductCode: row.Product2.ProductCode,
                        ProductDescription: row.Product2.Description
                    },
                    row
                )
            ];
        }

        this.products = this.allProducts;

        this.error = undefined;
    } else if (result.error) {
        this.error = result.error;
        this.allProducts = undefined;
        this.products = undefined;
    }
}