Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've started seeing this error since the Spring 16 release when I retrieve an sobject from the Apex controller, update it and then send it back to the server. I originally thought this was down to a $serId attribute that was somehow added to my sobject instance in the client, but I've reproduced this without that attribute being involved.

The sequence of events is as follows:

  • The component is surfaced via Lightning for Visualforce
  • The component retrieves an sObject from the server
  • The sobject contains a populated lookup field - this took me a while to figure out!
  • The SObject is stored in an attribute
  • The SObject is retrieved from the attribute
  • The component invokes an action that takes the sobject as a typed parameter (i.e. not as a string)
  • an error occurs of 'Unable to read sobject'

I've managed to dwindle this down to a very simple example.

Apex Controller - two methods, one to retrieve an Account, the other to accept an Account and debug it out:

public class bg_SObjectTestCtrl {
    @AuraEnabled
    public static Account GetAccount()
    {
        List<Account> accounts=[select id from Account limit 1];
        Account acc=new Account(Name='Test Account',
                                ParentId=accounts[0].id);

        return acc;
    }

    @AuraEnabled
    public static void SendAccount(Account acc)
    {
        System.debug('Account = ' + acc);
    }
}

Lightning Component:

<aura:component controller="bg_SObjectTestCtrl">
    <aura:attribute name="acc" type="Account" />

    <button onclick="{!c.getFromServer}">Get the Account</button><br/>
    Account Name : {!v.acc.Name}<br/>
    <button onclick="{!c.sendToServer}">Send the Account</button>
</aura:component>

Lightning Component Controller:

({
    getFromServer : function(component, event, helper) {
        helper.getFromServer(component, event);
    },
    sendToServer : function(component, event, helper) {
        helper.sendToServer(component, event);
    }
})

Lightning Component Helper:

({
    getFromServer : function(cmp, ev) {
        var action=cmp.get('c.GetAccount');
        var self=this;
        action.setCallback(this, function(response) {
                self.actionResponseHandler(response, cmp, self, self.gotAccount);
        });
        $A.enqueueAction(action);
    },
    gotAccount : function(cmp, helper, acc) {
        cmp.set('v.acc', acc);
    },
    sendToServer : function(cmp, ev) {
        var action=cmp.get('c.SendAccount');
        var acc=cmp.get('v.acc');
        action.setParams({'acc' : acc});
        var self=this;
        action.setCallback(this, function(response) {
                self.actionResponseHandler(response, cmp, self, self.sentAccount);
        });
        $A.enqueueAction(action);
    },
    sentAccount : function(cmp, helper, acc) {
        alert('Sent account to server');
    },
    actionResponseHandler : function (response, component, helper, cb, cbData) {
        try {
            var state = response.getState();
            console.log('State = ' + state);
            if (state === "SUCCESS") {
                var retVal=response.getReturnValue();
                cb(component, helper, retVal, cbData);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        alert("Error message: " + errors[0].message);
                    }
                } 
                else {
                    alert("Unknown error");
                }
            }
        }
        catch (e) {
            alert('Exception in actionResponseHandler: ' + e);
        }
    }
})

For the sake of completeness, here is the Visualforce Page:

<apex:page sidebar="false" showHeader="false" standardStylesheets="false">
    <apex:includeLightning />
    <div id="lightning"/>

    <script>
        $Lightning.use("c:SObjectTestApp", function() {
            $Lightning.createComponent("c:SObjectTest",
                  {},
                  "lightning",
                  function(cmp) {
                    // any additional processing goes here
              });
        });    
    </script>
</apex:page>

and the Lightning Application that ties these things together:

<aura:application access="GLOBAL" extends="ltng:outApp">
    <aura:dependency resource="c:SObjectTest" />
</aura:application>    
share|improve this question
up vote 11 down vote accepted

So after quite a bit more investigation, the workaround for this is to set an sobjectType attribute on the sobject prior to sending it to the server. Thus if I update my sendToServer method as follows:

sendToServer : function(cmp, ev) {
    var action=cmp.get('c.SendAccount');
    var acc=cmp.get('v.acc');

    // set the sobjectType!
    acc.sobjectType='Account';

    action.setParams({'acc' : acc});
    var self=this;
    action.setCallback(this, function(response) {
            self.actionResponseHandler(response, cmp, self, self.sentAccount);
    });
    $A.enqueueAction(action);
}

I don't get the error and I'm able to debug my SObject out on the server.

To re-iterate, this only seems to be an issue when the component is in a Visualforce page and has a lookup field populated. (As an aside, the same thing happens when I create the sobject client side, but I usually expect to have to specify the sobjectType there anyway).

share|improve this answer
    
@bob Yes i have observed the same . Thanks for dropping it here – Mohith Shrivastava Mar 2 at 16:02
1  
Bob, Are you planning on writing a book for lightining components as well? I learnt so much from your Visualforce book and looking forward for lightining components. Thanks! – javanoob Mar 2 at 16:21
5  
Nothing planned at present. Lightning Components are shifting sands at the moment, but something I'll be considering in the future. Thanks for the kind words! – Bob Buzzard Mar 2 at 16:47
2  
Nice to see you back; your insights into VF were, and continue to be, helpful to me – cropredy Mar 2 at 17:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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