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 — >
((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); –>
DataTable after I got the response and set the data to dataTable –>
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.
Best Answer
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:
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). ...