12

When writing a controller for a Lightning Component, it is convenient to add the data transfer object classes as inner classes of the controller. This works fine for sending data to the client but I get a gack that includes a java.lang.UnsupportedOperationException when sending from client to server:

An internal server error has occurred\nError ID: 2066801247-4851 (-1600101374)\n\norg.auraframework.throwable.AuraExecutionException: apex://LifePaymentsController: java.lang.UnsupportedOperationException\n\tat .(apex://LifePaymentsController)\n\tat ui.services.facades.CoreLightningComponentFacadeImpl.runApexAction(CoreLightningComponentFacadeImpl.java:233) ...

Here is what the server-side looks like (the save1 method fails):

public class SaveRequest {
    @AuraEnabled public Payee[] newPayees;
    @AuraEnabled public Payment[] payments;
}

...

// Fails
@AuraEnabled
public static void save1(SaveRequest saveRequest) {
    System.debug(JSON.serializePretty(saveRequest));
}

// Works
@AuraEnabled
public static void save2(String jsonString) {
    SaveRequest r = (SaveRequest) JSON.deserializeStrict(jsonString, SaveRequest.class);
    System.debug(JSON.serializePretty(r));
}

and the client-side:

// Fails
var action = servicesComponent.get("c.save1")
action.setParams({ 
    "saveRequest": saveRequest
});

// Works
var action = servicesComponent.get("c.save2");
action.setParams({ 
    "jsonString": JSON.stringify(saveRequest)
});

The save2 alternative method (where deserialization is explicitly coded) works.

I interpret these results to mean that inner classes are still (April 2017) not fully supported in @AuraEnabled methods. Is that the case?

  • yes even I too faced this issue. looks like it is still not fully supported. We need to use json alternative way – Ratan Paul Apr 11 '17 at 9:19
  • Is it working if it's not an inner class ? I have errors too with a separate class. – Fabien Taillon Apr 11 '17 at 10:11
  • @FabienTaillon Oh bad assumption on my part. Is the JSON string approach the work-around you use too? – Keith C Apr 11 '17 at 10:25
  • 1
    I used the string approach both for top level class and inner class. Without string they are both crashing, with string they are both working. Is it what you are seeing too ? – Fabien Taillon Apr 11 '17 at 10:38
  • @FabienTaillon Haven't tried the top level classes (don't want the clutter) - I just assumed the problem was related to inner classes as there are various posts pointing at problems with inner classes. Looks like JSON string is today's answer... – Keith C Apr 11 '17 at 10:42
11

Unfortunately I wasn't able to make it work using the class directly, either with an inner class or even a top level class. Using the second solution with a String attribute in your AuraEnabled method and then deserialize it is the best solution I've found. It works for both inner class and top level class.

I've just published a blog post to list all the issues I've found with AuraEnabled types (unfortunately this one isn't the only one) and the workaround I used. You can find it here: https://blog.texei.com/lightning-components-auraenabled-method-parameters-whats-working-and-what-s-not-83c351356104

2

Spring 19 Update :

I just stumbled upon this question and I recently used something similar in Spring 19 so thought might answer this.

Inner classes are supported now, you have to use setter and getter in your AuraEnabled inner class variables.

So your code will be:

    public class MyApexClassController {


    @AuraEnabled
    public static ApexWrapper goGetMyData(ApexWrapper data) {
        System.debug('Inner class data: ' + JSON.serialize(data));    // This will print without giving GACK
        ApexWrapper aw= new ApexWrapper();  
        ad.Name = '222';
        return ad;

    }

    //Inner Apex Class
    public class ApexWrapper{
        @AuraEnabled
        public String Name {get;set;}   //123abc
    }

}

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.