[SalesForce] How to send List from Lightning component to Apex Controller

My question is bit similar to this. But I'm getting a Runtime exception in SF.
Not getting a compiler error, but in Apex, it's throwing,

FATAL_ERROR System.UnexpectedException: Salesforce System Error:
1996097431-19512 (-1753594556) (-1753594556)

and Callback fails with javascript error,

WARNING: Callback failed:
apex://MyDev.Test1Controller/ACTION$saveDataDML

I'm trying to send List from Helper to Apex controller.

Wrapper class:

public with sharing class Wrapperclass {

    @AuraEnabled
    public CustObjA__c Inv{get;set;}

    @AuraEnabled
    public CustObjB__c Trans{get;set;}

    @AuraEnabled
    public String userMsg{get;set;}
}

Aura markup:

<aura:attribute name="processedItems" type="Wrapperclass[]" access="public" />

My callback function:

saveScannedData: function(component) {

var itemList = component.get('v.processedItems');

// Run Asynchronous call to save data
var actSave = component.get("c.saveDataDML");
actSave.setParams({
    "listToSave": itemList
    //"listToSaveString": JSON.stringify(itemList)
    //"listToSaveString": $A.util.json.encode(itemList)
});

actSave.setCallback(this, function(response) {

    var state = response.getState();

    console.log('Save response: '+state);

    if (component.isValid() && state == "SUCCESS") {
        var ret = response.getReturnValue();
        console.log(ret);
    } else {
        console.log(state);
        console.log(errors[0]);

        var errors = response.getError();

        console.log('No. of error msgs: ' + errors.length);

        if (errors) {
            if (errors[0] && errors[0].message) {
                console.log("Error message: " + errors[0].message);
            } else {
                console.log('Weird error: ' + errors[0].message);
            }

        } else {
            console.log("Unknown error");
        }
    }


});

$A.enqueueAction(actSave);

}

Apex controller:

public static List<Wrapperclass> saveDataDML(List<Wrapperclass> listToSave){
           for(Wrapperclass item :listToSave){
                system.debug(item);
                String errMsg = valWrapperclass(item);

                if (String.isEmpty(errMsg)){
                    // Add to Transaction list
                    dml_listTrans.add(item.Trans);
                }else{
                    item.userMsg = errMsg;
                    hasError = true;
                }
           }

...

It actually fails just before the below line in Apex controller.

for(Wrapperclass item :listToSave)

Appreciate any help on this.
Thanks.

Best Answer

Fixed using this approach.

In Java script Callback,

var actSave = component.get("c.saveDataDML");
        actSave.setParams({
            "listToSaveString": JSON.stringify(itemList)
        });

and in Apex Controller, Deserialized an casted as below.

@AuraEnabled
public static List<Wrapperclass> saveDataDML(String listToSaveString){

List<Wrapperclass> listToSave = (List<Wrapperclass>)JSON.deserialize(listToSaveString, List<Wrapperclass>.class);
Related Topic