11

Why do I get an Internal Salesforce.com Error when trying to pass an array of sObject values to an Apex controller action method?

I've posted a simple gist to demonstrate this problem to GitHub: https://gist.github.com/martyychang/76867c92f19808b6a7b7

The way to reproduce the problem is:

  1. Enable debug logging for yourself
  2. Launch oneLead.app (after you've created everything in the gist and tweaked the namespace references)
  3. Submitting a single lead works fine using the first Submit button, as expected
  4. Adding multiple leads and then submitting all of them using the bottom Submit button causes the Internal Salesforce.com Error

Is there something simple that I'm doing wrong? All I want to do is pass a List object as a parameter to my Apex controller from my Lightning component.

2
  • 2
    I observed the same with a List<String> when doing this code and had to workaround it by converting the List to a String. Commented Nov 7, 2014 at 0:10
  • It's a year after the last post and I still have the same problem. I got around it by making my list a comma delimited String and then tokenizing that on the server side. Any word on whether or not this will be fixed soon?
    – user26148
    Commented Nov 5, 2015 at 22:03

2 Answers 2

7

The problem is deep inside of the transport/marshalling interface layer between Lightning Components and Apex and will need to be fixed by my team.

For now I have developed a generic workaround using a small amount of Apex.

public class OneLeadController {

    @AuraEnabled
    public static Id createLead(Lead newLead) {
        insert newLead;
        return newLead.Id;
    }

    @AuraEnabled
    public static List<Id> createLeads(String newLeads) {
        List<SObject> newSObjectsList = convertJSONToListOfSObject(newLeads);

        insert newSObjectsList;

        List<Id> newIds = new List<Id>();
        for (SObject o : newSObjectsList) {
            newIds.add(o.Id);
        }

        return newIds;
    }

    @AuraEnabled
    public static Lead newLead() {
        return (Lead)Lead.sObjectType.newSObject(null, true);
    }

    private static List<SObject> convertJSONToListOfSObject(String json) {
        Object[] values = (Object[])System.JSON.deserializeUntyped(json);

        List<SObject> newSObjectsList = new List<SObject>();
        for (Object v : values) {
            Map<String, Object> m = (Map<String, Object>)v;

            Schema.SObjectType targetType = Schema.getGlobalDescribe().get((String)m.get('sobjectType'));

            SObject o = targetType.newSObject();

            Map<String, Schema.SObjectField> fields = targetType.getDescribe().fields.getMap();
            for (String fieldName : m.keySet()) {
                // Filter out any psuedo fields such as LastNameLocal
                Schema.SObjectField fi = fields.get(fieldName);
                if (fi != null) {
                    if (fi.getDescribe().isCreateable() && fi.getDescribe().isUpdateable()) {
                        o.put(fieldName, m.get(fieldName)); 
                    }
                }
            }

            newSObjectsList.add(o);
        }

        return newSObjectsList;
    }
}

and a small corresponding change to the client side controller (oneLeadController.js) calling this:

({
    save : function(component, event, helper) {
        var self = this;

        var createLeads = component.get("c.createLeads");
        createLeads.setParams({
            "newLeads": $A.util.json.encode(component.get("v.leads"))
        });

        createLeads.setCallback(self, function(a) {
            if (a.getState() === "SUCCESS") {
                console.log("returned: %o", a.getReturnValue());
            } else {
                alert($A.util.json.encode(a.getError()));
            }
        })

        $A.enqueueAction(createLeads);
    }
})
3
  • 2
    are there any ETA when this issue will be fixed? And will it be fixed at all ?
    – steals
    Commented Nov 10, 2015 at 15:57
  • Doug, this is ridiculous, 2 years now and it still doesn't work? System.debug(items.getSobjectType()); // null, lol when items is a List<Contact>. It seems everything is OK with single records, it's "just" the collection that's broken because my upsert complains at it: "System.TypeException: DML on generic List<SObject> only allowed for insert, update or delete"
    – eyescream
    Commented Nov 29, 2016 at 14:28
  • 1
    Seriously this is ridiculous. Still it is not fixed. I'm trying to pass list of wrapper to apex and getting "Internal Salesforce.com Error" :( The workaround suggested to pass string is not sufficient as string too has limit of 600000 chars. Commented May 3, 2018 at 14:34
4

This should work (both scenarios)- I'm looking into what the underlying error is. I suspect this is specific to how our json deserializer is wired to Apex. You should not have to drop to serializing to strings manually.

7
  • any update on this issue? I am running into similar internal server errors when passing Apex wrapper classes as parameters on Spring '16. While passing a JSON string is fine for our internal dev team, these methods are going to be exposed as part of a managed package so asking someone else to give us a correctly formatted string is really not ideal.
    – dsharrison
    Commented May 27, 2016 at 18:24
  • This is a very big deal for our development because we were planning on making a component that has checkboxes, to overcome the problem that Related Lists in lightning do not have checkboxes. Now our component is generating this same internal server error.
    – SeanW
    Commented Jun 15, 2016 at 19:46
  • 5
    Still happening folks. Pretty basic functionality to not be working. Commented Jun 27, 2016 at 19:26
  • Any update on this? This is a huge blocker for us at the moment.
    – Mark Keats
    Commented Jul 15, 2016 at 10:08
  • Same here...any updates on this?
    – Sarang
    Commented Nov 18, 2016 at 12:56

You must log in to answer this question.

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