Apex – How to Display Response Data from Apex Controller in DataTable

apexapidatatablejslightning-aura-components

I want to display data that I'm getting from API response in a datatable.

The APEX method returns JSON in this format:

{
    "data": [
        [
            "765919758146423601",
            "5ebd304a4cec1000",
            "2021-01-13T18:38:05",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ],
        [
            "2402015774021312251",
            "48566e2f521a4000",
            "2021-01-12T21:19:48",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ],
        [
            "3472999688268527503",
            "af3b292e27638000",
            "2021-01-12T22:45:36",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ],
        [
            "7787867248858577125",
            "7ffb01dfb283d400",
            "2021-01-14T09:02:02",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ],
        [
            "10928117865478904202",
            "84132d38a08b2000",
            "2021-01-14T11:05:20",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ],
        [
            "14601725682851508262",
            "a3c3730b1fd0ab14",
            "2021-01-15T03:31:55",
            "1920x1080",
            [
                0,
                "Desktop"
            ]
        ]
    ],
    "meta": {
        "columns": [
            "session_id",
            "visitor_id",
            "timestamp",
            "resolution",
            "device_type"
        ],
        "count": 6
    }
}

The columns of the datatable are set dynamically in this manner:

for (var i in mustHaveSessionLabelColumns) {
   dataTableColumnList.push({
      label: mustHaveSessionLabelColumns[i],
      fieldName: responseList[i],
      type: 'text'
    }); 
}
component.set("v.columns",dataTableColumnList);

When I test the aura:app I get correct amount of columns with correct fieldName&type (Checked with console.log) but I have trouble mapping the responseData to datatable data="v.dataTableData"

<lightning:datatable
    keyField="id"
    data="{!v.dataTableData}"
    columns="{! v.columns }"
    hideCheckboxColumn="true"
    resizeColumnDisabled="true"
    minColumnWidth="100"
    maxColumnWidth="1000" 
    showRowNumberColumn="true"/>

enter image description here

Best Answer

You need to parse your JSON into JavaScript Object and then manipulate with that object.

If you always get the same JSON format the Code for you will look in next way :

Apex :

public with sharing class ParseJsonIntoDatatableController {
    @AuraEnabled
    public static string getJSONData(){
        try {
            String jsonData;
            // somw your logic which gets JSON Data
            return jsonData;
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
    }
}

**Aura JS : **

({
    init : function(component, event, helper) {
        // helper constant for column Labels
        const columnLabelMap = {
            session_id : 'Session Id',
            visitor_id : 'Visitor Id',
            timestamp : 'Time',
            resolution : 'Resolution',
            device_type : 'Device Type',
        }
        var action = component.get("c.getJSONData");
        // the callback for parsing data from JSON
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                let responseData = JSON.parse( response.getReturnValue() );
                let dataTableColumns = []
                responseData.meta.columns.forEach( column => {
                    dataTableColumns.push( 
                        {
                            label : columnLabelMap[column] ? columnLabelMap[column] : column,
                            fieldName : column,
                            type: 'text'
                        }
                    )
                });
                component.set( "v.columns" , dataTableColumns );
                let dataForDatatable = []
                responseData.data.forEach( element => {
                    dataForDatatable.push( 
                        {
                            session_id : element[0],
                            visitor_id : element[1],
                            timestamp : element[2],
                            resolution : element[3],
                            device_type : element[4][1],
                        }
                    )
                });
                component.set( "v.dataTableData" , dataForDatatable );
            }
        });
        $A.enqueueAction(action);
    }
})

**Aura HTML : **

<aura:component controller="ParseJsonIntoDatatableController" implements="flexipage:availableForAllPageTypes" access="global">
    <aura:attribute name="dataTableData" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    <!-- handlers-->
    <aura:handler name="init" value="{! this }" action="{! c.init }"/>


    <!-- the container element determine the height of the datatable -->
    <div style="height: 300px">
        <lightning:datatable
            keyField="session_id"
            data="{! v.dataTableData }"
            columns="{! v.columns }"
            hideCheckboxColumn="true"
            resizeColumnDisabled="true"
            minColumnWidth="100"
            maxColumnWidth="1000" 
            showRowNumberColumn="true"
        ></lightning:datatable>
    </div>
</aura:component>

Note :
this code will only work for your JSON format,
you can modify the parser for your wishes,
it will be good to set the column types dynamically as well

With that code you will get the next datatable enter image description here

Related Topic