5

In a clientside controller of a Lightning Component I want to retrieve a complex structure of data. The reason is, that I don't want to fire more than on action to avoid multiple roundtrips. Therefore I want to use a class defined in APEX as return value of an action like this:

({
    init : function(component, event, helper) {
        console.log('init');
        var action = component.get("c.getData");        
        action.setCallback(this, function(response) {
            console.log(response.getReturnValue());
            // do something funny here later...
        });
        $A.enqueueAction(action);
    }, 
})

The APEX controller looks like that

public class elfClientOpportunityList { 
    public class data {
        public List<Opportunity>        opportunities               { get; set; }
        public String                   text                        { get; set; }
        public String                   text2                       = 'text2';
        public data() {
            this.opportunities = new List<Opportunity>();           
            this.text   = 'text1';
        }
    }
    @AuraEnabled public static data     getData() {
        data result = new data();
        result.opportunities = (List<Opportunity>) Database.query(
            ' SELECT Name FROM Opportunity LIMIT 3 '
        );
        return result; 
    }
    @AuraEnabled public static Opportunity[]    getOpps() {
        return (List<Opportunity>) Database.query( 
            ' SELECT Name FROM Opportunity LIMIT 3 '
        );
    }
}

Now looking a the console output I get only an empty object

enter image description here

However after I change the js-controller to fetch only a list of SObjects (using the last function of the APEX controller)

var action = component.get("c.getOpps"); 

it brings up a non-empty result (as expected)

enter image description here

Are complex data structures in form of classes supported as return values? If so, what am I doing wrong here?

Just to be sure nothing went wrong in getData() I double checked the result via execute anonymous and it works as expected:

32.0 APEX_CODE,WARN;APEX_PROFILING,WARN;CALLOUT,WARN;DB,WARN;SYSTEM,WARN
17:40:08.127 (127677683)|EXECUTION_STARTED
17:40:08.127 (127693692)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
17:40:08.188 (188291840)|USER_DEBUG|[235]|WARN|{
   "text2" : "text2",
   "text" : "text1",
   "opportunities" : [ {
      "attributes" : {
         "type" : "Opportunity",
         "url" : "/services/data/v35.0/sobjects/Opportunity/00626000002CW7PAAW"
      },
      "Name" : "Horst Meier - 10247 Berlin - 2015/10",
      "Id" : "00626000002CW7PAAW"
   }, {
      "attributes" : {
         "type" : "Opportunity",
         "url" : "/services/data/v35.0/sobjects/Opportunity/00626000002BVH0AAO"
      },
      "Name" : "- 12345 Berlin - 2015/10",
      "Id" : "00626000002BVH0AAO"
   }, {
      "attributes" : {
         "type" : "Opportunity",
         "url" : "/services/data/v35.0/sobjects/Opportunity/00626000002CWe2AAG"
      },
      "Name" : "Heinz Meier -    - 2015/10",
      "Id" : "00626000002CWe2AAG"
   } ]
}
17:40:08.188 (188371268)|CODE_UNIT_FINISHED|execute_anonymous_apex
17:40:08.190 (190373538)|EXECUTION_FINISHED
8

Every property returned should be annotated as @AuraEnabled.

 public class Data {

    @AuraEnabled
    public List<Opportunity> Opportunities { get; set; }

    @AuraEnabled
    public String Text { get; set; }

    @AuraEnabled
    public String Text2 = 'text2';
    public Data() {
        this.Opportunities = new List<Opportunity>();           
        this.Text = 'text1';
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.