I am passing a list of SObjects with child relationships to a Lightning Web Component. If I query and pass my query results back to my LWC component directly, this works.

In Apex:

return [
    SELECT Id, (SELECT Id, LastName FROM Contacts)
    FROM Account

In LWC, I get a nice, nested JavaScript object:

    Id: "0012D00000PDWKAQA5", 
    Contacts: {
      Id: '0032D00000Ni9yZQAR',
      LastName: 'Test' 

Now I have a requirement that involves adding and removing child records before returning the response to my LWC component. But I'm noticing some weird behavior when I try to manipulate the child relationship, which I had assumed was just a List type. When I use add(), nothing is added. When I use remove(), nothing is removed. And yet, no exception is thrown.

For example, you can run this in Execute Anonymous:

Account acc = [
    SELECT Id, (SELECT Id, LastName FROM Contacts)
    FROM Account
    WHERE Id IN (SELECT AccountId FROM Contact)
    LIMIT 1
Integer contactNum = acc.Contacts.size();
acc.Contacts.add(new Contact(LastName = 'Test'));
System.assertEquals(contactNum + 1, acc.Contacts.size());


System.assertEquals(contactNum - 1, acc.Contacts.size());

I tried working around this by setting acc.Contacts directly, e.g. acc.Contacts = new List<Contact>();. This returns an exception: "Field is not writeable: Account.Contacts"

Any help?

  • 1
    One of the approaches could be to do a deserialization (f.e. serialize to string, then deserialize to map<String, Object>, call put on it with "Contacts" as field name, and serialize it back". Personally I would not go with route, but use custom wrapper class to make it more flexible and controllable
    – kurunve
    Sep 18, 2020 at 18:07
  • These are OK workarounds as workarounds go. It's a layer of complexity I would generally hope to avoid, but that might not be possible in this case. And I'm still sort of looking for some deeper insight into what acc.Contacts is, if not a List, and why add() and remove() fail silently on whatever it is. Sep 18, 2020 at 18:25
  • 1
    acc.Contacts is definitely a List (verified using acc.Contacts instanceOf List<Contact> in your sample code), but looks like apex is treating it as immutable. By immutable, I mean the contacts list itself is read-only (or restricted for add/ remove) but fields within the retrieved contact records are writeable. I guess SF would have some strong reasons to do this, but couldn't find any SF documentation that explains about this.
    – arut
    Sep 18, 2020 at 20:02


You must log in to answer this question.

Browse other questions tagged .