3

I have an Parameters Apex class for common properties, the real class currently has over 17 properties:

public class Parameters {

    @AuraEnabled
    public String eventId;
    @AuraEnabled
    public String locationId;
    @AuraEnabled
    public String personId;
    @AuraEnabled
    public Long starts;
    @AuraEnabled
    public Long ends;
}

I don't want to keep typing these common properties as parameters into methods, so I want to pass the Parameters object around.

Therefore, I could like to use it as a parameter for an Apex controller method:

@AuraEnabled
public static boolean exampleControllerMethod(Parameters params) 
{
    if (params != null)
    {
        System.debug(params);
        return true;
    }

    return false;
}

The controller is called from a Lightning Component helper method:

exampleHelperMethod: function(component)
{                
    var action = component.get("c.exampleControllerMethod"); 

    var params = this.getParameters(component);

    action.setParams({'params': params});

    action.setCallback(this, function(response) {
        var state = response.getState();
        if(component.isValid() && state === "SUCCESS"){
            var result = response.getReturnValue();
            console.log(result);
        }
    });

    $A.getCallback(function() {
        $A.enqueueAction(action); 
    })();
},

I populate the JavaScript params variable in this helper method:

getParameters : function(c) 
{ 
    return {
        'eventId': c.get("v.eventId"),
        'locationId': c.get("v.locationId"),
        'personId': c.get("v.personId"),
        'starts': c.get("v.starts"),
        'ends': c.get("v.ends")
    };
},

I get this in the Apex Debug logs:

16:55:35.0 (131244)|EXECUTION_STARTED
16:55:35.0 (137794)|CODE_UNIT_STARTED|[EXTERNAL]|Aura
16:55:35.0 (3453904)|CODE_UNIT_STARTED|[EXTERNAL]|01p0O00000BUy1u|ExampleController.exampleMethod
16:55:35.0 (3640477)|HEAP_ALLOCATE|[72]|Bytes:3
16:55:35.0 (3721140)|HEAP_ALLOCATE|[77]|Bytes:152
16:55:35.0 (3744001)|HEAP_ALLOCATE|[342]|Bytes:408
16:55:35.0 (3762162)|HEAP_ALLOCATE|[355]|Bytes:408
16:55:35.0 (3779417)|HEAP_ALLOCATE|[467]|Bytes:48
16:55:35.0 (3817152)|HEAP_ALLOCATE|[139]|Bytes:6
16:55:35.0 (3891112)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:28
16:55:35.0 (3909871)|METHOD_ENTRY|[1]|01p0O00000BUy1u|ExampleController.ExampleController()
16:55:35.0 (3922160)|STATEMENT_EXECUTE|[1]
16:55:35.0 (3931441)|STATEMENT_EXECUTE|[1]
16:55:35.0 (3937276)|METHOD_EXIT|[1]|ExampleController
16:55:35.0 (4055332)|FATAL_ERROR|Internal Salesforce.com Error
16:55:35.0 (4079642)|CODE_UNIT_FINISHED|ExampleController.exampleMethod
16:55:35.0 (8933960)|CODE_UNIT_FINISHED|Aura
16:55:35.0 (12133134)|EXECUTION_FINISHED

Of which the most interesting, yet still unhelpful message is:

16:55:35.0 (4055332)|FATAL_ERROR|Internal Salesforce.com Error

1
  • You will need to change the parameter type in your apex to that of String. And then in your controller, you will need to deserialize the incoming values. Though there's no mention of what works vs. what not as parameter in aura enabled apex methods, but using apex/objects seem not to work. You can find some details on this post.
    – Jayant Das
    Commented Apr 26, 2018 at 13:37

3 Answers 3

6

In case anyone is still looking for an answer to this, I found adding {get; set;} to the @AuraEnabled object fields enabled the object to be passed in as a parameter from Aura/LWC. String serialization and deserialization is NOT needed.

So the example given in the question should be:

public class Parameters {
    @AuraEnabled
    public String eventId {get; set;}
    @AuraEnabled
    public String locationId {get; set;}
    @AuraEnabled
    public String personId {get; set;}
    @AuraEnabled
    public Long starts {get; set;}
    @AuraEnabled
    public Long ends {get; set;}
}
1
  • 1
    Hi, What about in the LWC. Do you send in a JSON object with properties that match the properties in the class?
    – Victor
    Commented Mar 3, 2020 at 20:35
5

Currently I have a workaround...

Which involves using:

JSON.stringify(params);

In the JavaScript helper method:

exampleHelperMethod: function(component)
{                
    var action = component.get("c.exampleControllerMethod"); 

    var params = this.getParameters(component);

    action.setParams({'jsonString': JSON.stringify(params) });

    action.setCallback(this, function(response) {
        var state = response.getState();
        if(component.isValid() && state === "SUCCESS"){
            var result = response.getReturnValue();
            console.log(result);
        }
    });

    $A.getCallback(function() {
        $A.enqueueAction(action); 
    })();
},

And to deserialize:

Parameters p = (Parameters)JSON.deserialize(jsonString, Parameters.class);

In the Apex controller method:

@AuraEnabled
public static boolean exampleControllerMethod(String jsonString) 
{
    Parameters p = (Parameters)JSON.deserialize(jsonString, Parameters.class);

    if (p != null)
    {
        System.debug(p);
        return true;
    }

    return false;
}
0

Just to update this topic in case anyone is having a similar issue:

  1. Serialization and deserialization are not needed as mentioned by @monkeyhandz
  2. To ensure successful deserialization, it is essential to add the @AuraEnabled annotation to the attributes of the class. This will make the attributes accessible to the Lightning components.
  3. For your controller method to correctly receive and process a JSON payload, the payload must contain a key that matches the parameter name of the method.

So following the given example we could be doing:

public class Parameters {
    @AuraEnabled
    public String eventId {get; set;}
    @AuraEnabled
    public String locationId {get; set;}
    @AuraEnabled
    public String personId {get; set;}
    @AuraEnabled
    public Long starts {get; set;}
    @AuraEnabled
    public Long ends {get; set;}
}

Controller

@AuraEnabled
//Don't forget to match the key name in your payload with the parameter name in this method. E.g: [action.setParams({'parameters': JSON.stringify(params) })]
public static boolean exampleControllerMethod(Parameters parameters) { 
   system.debug('Event ID is:' + parameters.eventId);
}

Javascript Method

exampleHelperMethod: function(component)
{                
    var action = component.get("c.exampleControllerMethod"); 
    var params = this.getParameters(component);
    //The key 'parameters' must match the parameter name in your Controller
    action.setParams({
        'parameters': {
            'eventId': c.get("v.eventId"),
            'locationId': c.get("v.locationId"),
            'personId': c.get("v.personId"),
            'starts': c.get("v.starts"),
            'ends': c.get("v.ends")
         }
    }); 
    action.setCallback(this, function(response) {
        var state = response.getState();
        if(component.isValid() && state === "SUCCESS"){
            var result = response.getReturnValue();
            console.log(result);
        }
    });

    $A.getCallback(function() {
        $A.enqueueAction(action); 
    })();
},

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .