[SalesForce] Passing list of object form Apex controller to lightning component

I want to create a page that display a list of object. I get the list of the objects from a table. then i pass it to javascript controller to display it in the lightning component. My code is below :

Controller Apex

@AuraEnabled
public static List<BatchToBeExecuted> getBatchs (){
 List<BatchToBeExecuted>  arrayItems = new BatchToBeExecuted[]{};
 List<SICo_BatchTobeExecuted__mdt> listBatchs = [SELECT Id,DeveloperName, 
   BatchSize__c FROM SICo_BatchTobeExecuted__mdt ];
 if(!listBatchs.isEmpty()){
   for( SICo_BatchTobeExecuted__mdt aBatch : listBatchs){
     arrayItems.add(newBatchToBeExecuted(aBatch.DeveloperName,aBatch.BatchSize__c));
   }
 } 
 System.debug('return value'+arrayItems);
 return arrayItems ;
}

Controller Javascript

init : function(component, event, helper) {
    let action = component.get("c.getBatchs");
    action.setCallback(this,function(response){
      const state = response.getState();
      console.log('state='+state);
      if(state==="SUCCESS"){
        var batchs = response.getReturnValue();
        var result = [{batchSize:2000, name:"SICo_DeleteArchive_Batch"}];

        component.set("v.aBatchToBeExecuted", result);
        console.log('return result='+JSON.stringify(batchs)) ; 
      }

The console.log of JSON.stringify(return value) show a blank table

<table>

   <aura:iteration items="{!v.aBatchToBeExecuted}" var="batchToBeExecuted">

        {!batchToBeExecuted.name}
        {!batchToBeExecuted.batchSize}
    </aura:iteration>

    <lightning:button onclick="{!c.getString}" label="Update"/>
</table>

Best Answer

You need to call enqueueAction in your init function, and set the return value to an attribute on your component. You may find it helpful to check for the ERROR and INCOMPLETE states, and not just SUCCESS.

init : function(component, event, helper) {
    var getBatchsAction = component.get("c.getBatchs");
    getBatchsAction.setCallback(this, function(response){
        var state = response.getState();
        if(component.isValid() && state === "SUCCESS"){
            component.set("v.aBatchToBeExecuted", response.getReturnValue());
        }
        else if(state === "ERROR"){
            var errors = response.getError();
            if(errors) {
                if(errors[0] && errors[0].message){
                    console.log("Error message: " + errors[0].message);
                }
                else{
                    console.log("unknown error");
                }
            }
        }
        else if(state === "INCOMPLETE"){
            console.log("Incomplete action. The server might be down or the client might be offline.");
        }
    });
    $A.enqueueAction(getBatchsAction);
},

Include a handler for initialization.

<aura:component controller="MyController">
    <aura:attribute name="aBatchToBeExecuted" type="BatchToBeExecuted[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>

    <table>
        <aura:iteration items="{!v.aBatchToBeExecuted}" var="batchToBeExecuted">
            <tr>
                <td>{!batchToBeExecuted.name}</td>
                <td>{!batchToBeExecuted.batchSize}</td>
            </tr>
        </aura:iteration>
    </table>
    <lightning:button onclick="{!c.getString}" label="Update"/>
</aura:component>

Since you are returning an apex object instead of a custom object, you will need to annotate the variables you want to use with @AuraEnabled

public with sharing class BatchToBeExecuted {
    @AuraEnabled
    public String name { get; set; }

    @AuraEnabled
    public Integer batchSize { get; set; }
}

In order to get useful error messages in lightning back from apex, you will need to wrap exceptions in an AuraHandledException.

@AuraEnabled
public static List<BatchToBeExecuted> getBatchs (){
    try{
        List<BatchToBeExecuted> arrayItems = new BatchToBeExecuted[]{};
        List<SICo_BatchTobeExecuted__mdt> listBatchs = [SELECT Id, DeveloperName, BatchSize__c FROM SICo_BatchTobeExecuted__mdt];
        if(!listBatchs.isEmpty()){
            for(SICo_BatchTobeExecuted__mdt aBatch : listBatchs)
                arrayItems.add(new BatchToBeExecuted(aBatch.DeveloperName, aBatch.BatchSize__c));
        }
        System.debug('return value'+arrayItems);
        return arrayItems;
    }
    catch(Exception e){
        //this allows lightning components to see the exception message
        System.AuraHandledException ahe = new System.AuraHandledException(e.getMessage());
        //this makes it so the exception is still readable in the debug logs
        ahe.setMessage(e.getMessage());
        throw ahe;
    }
}

If there aren't any errors and you are still having trouble, here are some common mistakes to check for:

  • Is the attribute name spelled correctly everywhere? Remember these are case sensitive
  • Are your javascript variables spelled correctly? These are also case sensitive
  • Did you include the "v." value provider when referencing the attribute?
  • Does the user running the application have permission to all of the objects/fields you are referencing?
  • If your apex method accepts parameters, did you call setParams on the action before enqueuing it? Are the parameter names spelled correctly?