0

I want to display the data that I get from apex controller to dataTable and I have trouble mapping the different columns correctly to the map.

I have a @AuraEnabled method that returns List of Object on call:

EDIT 1:

if (res.getStatusCode() == 200){ 
                Map<String,Object> results = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
                List<Object> responseData = (List<Object>) results.get('data');
                // Return data List<Object>
                return responseData;                    
            }

When I make the API call, the server always returns 3 values + x (those who you required) per row, like so -- >

Apex execute anonymous system.debug of the responseJSON

((1802523701456533, 701300b97e2e1000, 2021-03-08T03:09:57, (1, Smartphone)),(15250809629146723, 5957676d3b753f69, 2021-02-18T07:19:04, (1, Smartphone)), (20487780899778413, 7a5911e7f5731400, 2021-01-26T15:54:48, (0, Desktop)), (27450806533608027, 186af40e19b1cfdf, 2021-02-27T00:55:45, (1, Smartphone)), (41195804276029081, 2ec0802a5c592800, 2021-01-22T06:33:13, (0, Desktop)), (41346057691525410, 67e89542fb518400, 2021-02-06T07:47:28, (1, Smartphone)) ....

The first one is Session ID, second Visitor ID and Timestamp

I want to display in this datatable:

Aura cmp:

<aura:component>

        <!-- ATTRIBUTES -->
        <aura:attribute name="columns" type="List"/>
        <aura:attribute name="dataTableData" type="Object" default=""/>
        
        <aura:attribute name="parentValue" type="String" default=""/>
        <!-- HANDLERS-->
        <aura:handler name="init" value="{!this}" action="{!c.init}"/>
        
        <div style="height: 1000px">
            <lightning:datatable
                                 keyField="id"
                                 data="{! v.dataTableData }"
                                 columns="{! v.columns }"
                                 hideCheckboxColumn="true"
                                 resizeColumnDisabled="true"
                                 minColumnWidth="100"
                                 maxColumnWidth="1000" />
        </div>
    </aura:component>

Controller.js

var selectedDimensions = component.get("v.columns");
        var columnsDataTable = [];
        
        if(component.get("v.parentValue") === "Sessions"){
            var columnsDataTableSession = ['Session ID','Visitor ID', 'Timestamp'];
            for (var i in columnsDataTableSession){
                columnsDataTable.push({label: columnsDataTableSession[i],
                                       fieldName: columnsDataTableSession[i],
                                       type: 'String'
                                      });
            }
        } 
 else {
                alert("Can't fetch the data right now, try later.");
        }
        
        for (var i in selectedDimensions) {
            columnsDataTable.push({label: selectedDimensions[i],
                                   fieldName: selectedDimensions[i],
                                   type: 'String'
                                  });
        }
        component.set("v.columns", columnsDataTable);
    },

With the for loop I'm declaring columns dynamically for the datatable based on previously selected picklist values.

I'm fetching data from another component and sending it to display in this one.

Fetching function is:

fetchData : function(component, event, helper) {
        
        if(component.get("v.parentValue") === "Sessions"){
            var action = component.get("c.fetchSessions");
            action.setParams({
                webSite: component.get('v.webSiteId'),
                selectedSiteName: component.get('v.selectedSite'),
                stringColumns: component.get('v.childValue'),
                date_from: component.get('v.dateFrom'),
                date_to: component.get('v.dateTo'),
                token: component.get('v.accessToken')
            });
            action.setCallback(this, function(response){
                var state = response.getState();
                if(state === "SUCCESS") {
                    var responseData = response.getReturnValue();
                    var jsonString = JSON.parse(JSON.stringify(responseData));
                    alert(responseData);
                    alert(jsonString);
                    component.set("v.dataTableData", jsonString);
                }
                else {
                    alert(response.getBody());;
                }
            });
            $A.enqueueAction(action); 

alert(responseData); -->

Alert(responseData) that I get after calling apex method in aura

DataTable after I got the response and set the data to dataTable --> Datatable empty

So, how can I map the returnData to the datatable knowing that I will always have 3 columns returning Visitor ID, Session ID, Timestamp + those that I request?

Thank you.

0

1 Answer 1

1

The datatable "data" property expects an Array of objects with key/value pairs. The key should map to the "fieldName" property of the columns array.

So, if I'm reading the code correctly, your return object would need to look something like this:

[ 
  { "Session ID" : "1802523701456533",
    "Visitor ID" : "701300b97e2e1000",
    "Timestamp"  : "2021-03-08T03:09:57"
  }, ...
]

You'll need to do some post processing on your server result to get it in a similar format for use in the datatable component.

As an example, you can loop through each object in the 'jsonString' array, split the string on "," (https://www.w3schools.com/jsref/jsref_split.asp) delimiter and assign the values as needed. You may need to strip whitespace as well. This approach is very tightly coupled to the result of the HTTP callout, so I wouldn't recommend it unless you know it will never change. (I haven't tested the code below, but should work). ...

   if(state === "SUCCESS") {
     var responseData = response.getReturnValue();
     var jsonString = JSON.parse(JSON.stringify(responseData));
     var tableArr = [];
     jsonString.forEach(row => {
        var strParts = row.split(",");
        tableArr.push({
           "Session ID": strParts[0],
           "Visitor ID": strParts[1],
           "Timestamp": strParts[2],
        });
     });
     component.set("v.dataTableData", tableArr);

     ...
8
  • Can't I do the post processing in my javascript controller in Aura when I get the JSON string?
    – Stojchesky
    Commented Aug 31, 2022 at 15:04
  • @Stojcheski Yes, you can.
    – sfdcfox
    Commented Aug 31, 2022 at 15:59
  • @sfdcfox Any suggestion or useful links on how would I approach this? Because I haven't deserialize a JSON string in aura js controller and I have no ideas.
    – Stojchesky
    Commented Aug 31, 2022 at 18:32
  • @Stojcheski you can look at some of the string manipulation methods available in JavaScript, e.g. split. This could get messy though, especially if the return object changes format unexpectedly. Do you have any control/input on the return format from the API callout? Your problem could be solved more easily if the API returned a JSON string, in similar format to that in the answer above.
    – BenBates
    Commented Aug 31, 2022 at 21:48
  • I've updated my question. The API call returns JSON string and I deserialize the string and only return 'data' from JSON string to aura as List of Objects.
    – Stojchesky
    Commented Sep 1, 2022 at 6:25

You must log in to answer this question.

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