Custom Lightning Component Related List With Real-Time REST Data

How to build a custom lightning component related list with real-time REST data. For this tutorial, I’ll show a technique on how to integrate external data and display the data real-time as a related list in Salesforce. This would not use an external object but a simple custom related list component that uses lightning:datatable base component and a controller than retrieves data via callout to an external REST resource and display them in Salesforce.

This is how it would look like.

For this, I’m calling this a static REST resource that returns the following JSON response.

[
{
"Id": "0d284614-c4ec-424c-a5aa-04e28d06a4df",
"Date": "2016-10-14T08:34:10.8+00:00",
"RegistryAccountCode": "ABC",
"ClientId": 0,
"Category": "I",
"Description": "Distribution Advice 12102016.pdf",
"FileName": "ABC Distribution Advice 12102016.pdf"
},
{
"Id": "9924c58a-523a-4b29-a514-1c4d1d7a1d7e",
"Date": "2016-07-14T06:33:28.969+00:00",
"RegistryAccountCode": "DEF",
"ClientId": 0,
"Category": "I",
"Description": "Distribution Advice 13072016.pdf",
"FileName": "DEF Distribution Advice 13072016.pdf"
},
{
"Id": "fd07709a-330c-4ad4-9fe7-530928b33a44",
"Date": "2017-07-19T00:36:06.213+00:00",
"RegistryAccountCode": "CCC",
"ClientId": 0,
"Category": "I",
"Description": "Distribution Advice 14072017.pdf",
"FileName": "CCC Distribution Advice 14072017.pdf"
},
{
"Id": "7bb16dfc-9e65-4f70-a03b-af0e290e306e",
"Date": "2017-01-18T04:33:07.603+00:00",
"RegistryAccountCode": "DDD",
"ClientId": 0,
"Category": "I",
"Description": "Distribution Advice 17012017.pdf",
"FileName": "DDD Distribution Advice 17012017.pdf"
}
]

Next, we need to display this data in a related list in Salesforce. We create a simple lightning component that we can add using Lightning App builder.

Start with the following lightning component markup.

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="dataTableSampleREST">
<!-- attributes -->
<aura:attribute name="recordId" type="String"></aura:attribute>
<aura:attribute name="mydata" type="Object"></aura:attribute>
<aura:attribute name="mycolumns" type="List"></aura:attribute>
<aura:attribute name="noResults" type="String"></aura:attribute>
<!-- handlers-->
<aura:handler name="init" value="{! this }" action="{! c.init }"></aura:handler>
<article aura:id="gridContainer" class="slds-card slds-card_boundary">
<lightning:card title="Documents" iconName="standard:document">
<div class="slds-card__header slds-grid">
<aura:if isTrue="{!not(empty(v.mydata))}" >
<!-- the container element determine the height of the datatable -->
<lightning:datatable keyField="id"
data="{! v.mydata }"
columns="{! v.mycolumns }"
hideCheckboxColumn="true"
sortable="false"
onrowaction="{!c.getDocument}"></lightning:datatable>
</aura:if>
<aura:if isTrue="{!empty(v.mydata)}" >
<p>{!v.noResults}</p>
</aura:if>
</div>
</lightning:card>
</article>
</aura:component>

And controller that calls a helper.

({
init: function (cmp, event, helper) {
helper.fetchData(cmp);
}
})

The helper creates a server-side call that creates the REST callout. Then on the successful response, I’m setting the value for the mycolumns attribute by assigning a Javascript object assigning the properties of the column for the datatable. Then I simply assign the mydata attribute assigning and using JSON.parse to turn the response to a Javascript object. With that simple code, I have a related list.

Note: you do not need the var actions as this is for another method I’m working on.

({
fetchData: function (cmp) {
var action = cmp.get('c.getDocumentList');
action.setCallback(this, $A.getCallback(function (response) {
var state = response.getState();
if (state === "SUCCESS") {
if(JSON.parse(response.getReturnValue()) != null) {
var actions = [
{ label: 'Download', name: 'download' },
];
cmp.set('v.mycolumns', [
{
label: 'Date',
fieldName: 'Date',
type: 'date'
},
{ label: 'Description', fieldName: 'Description', type: 'text'},
{ label: 'FileName', fieldName: 'FileName', type: 'text'},
{ type: 'action', typeAttributes: { rowActions: actions } }
]);
cmp.set('v.mydata', JSON.parse(response.getReturnValue()));
} else {
cmp.set("v.noResults", "No records to display");
}
} else if (state === "ERROR") {
var errors = response.getError();
console.error(errors);
cmp.set("v.noResults", "An error occurred: No records to display");
}
}));
$A.enqueueAction(action);
}
})

Then for my controller, I have this simple call to my server

public class dataTableSampleREST {
@AuraEnabled
public static String getDocumentList() {
String strEndPoint = 'https://www.lopau.com/rest/accounts';
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(strEndPoint);
Http h = new Http();
system.debug('## => ' + req);
HTTPResponse res = h.send(req);
System.debug('## => ' + res.getBody());
if (res.getStatusCode() == 200) {
system.debug('## res.getBody() =>' + res.getBody());
return res.getBody();
}
return null;
}
}

Then I simply drop the component on Lightning App Builder to the related list section for a quick UI match. That should be it.

Recommended Books:

Leave a Reply

Your email address will not be published. Required fields are marked *