2

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

1 Answer 1

3

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

5
  • 1
    What if the number of columns are dynamic based on multiselect picklist and the data should be mapped appropriately?
    – Stojchesky
    Commented Sep 6, 2022 at 9:54
  • 1
    @Stojcheski I mentioned that this solution for particular JSON. In your case you need to get this picklist at first and then based on the picklist length and order create the data for the data-table. Commented Sep 6, 2022 at 10:08
  • 1
    So I would need another forEach loop for all columns before responseData.data.forEach and then .push column[0] : element[0], column[1] : element[1] or? I have posted the question for exact this problem that's why I'm bothering you.
    – Stojchesky
    Commented Sep 6, 2022 at 10:54
  • Thanks, it worked.
    – Maria
    Commented Sep 6, 2022 at 15:20
  • @Maria You are welcome, Please accept this answer as the one which resolved your issue. Thanks Commented Sep 6, 2022 at 15:23

You must log in to answer this question.

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