Removing properties JSON Objects (Aura & LWC)

2025-12-03

Salesforce automatically injects an attributes object into every sObject returned to Lightning (LWC and Aura).
It contains things like:

  • type (e.g., “Account”)
  • url (API reference path)

While this metadata is useful internally, it becomes noise when you:

  • serialize objects
  • compare JSON structures
  • send data to external APIs
  • log or store Salesforce records in a custom format

In these cases, it’s often necessary to remove every attributes property from an entire nested structure.

Here’s a clean explanation of how to do it, why it works, and how to improve it.


Why Do We Need to Remove attributes?

Consider a record returned from Apex or a wire adapter:

{
    Name: "Test Account",
    attributes: { type: "Account", url: "/sobjects/Account/001..." },
    Contacts: [
        {
            Name: "John Doe",
            attributes: { type: "Contact", url: "/sobjects/Contact/003..." }
        }
    ]
}

This JSON is fine inside Lightning, but:

  • JSON comparisons become unreliable
  • diffs contain metadata you don’t care about
  • external API calls often fail due to unexpected fields

The cleaned version should look like:

{
    Name: "Test Account",
    Contacts: [
        { Name: "John Doe" }
    ]
}

The Original Recursive Approach

A basic recursive function may look like this:

removeAttributes: function(obj) {
    if (!obj instanceof Array && !obj instanceof Object) {
        return;
    }     

    for (var i in obj) {
        if (obj instanceof Array || (obj instanceof Object && obj.hasOwnProperty(i))) {
            if (i === 'attributes') {
                // delete obj.attributes;
                // OR: push to a log array if you need to track them
            }
            this.removeAttributes(obj[i]);
        }
    }
}

It works, but it has weaknesses — especially the !obj instanceof Array check, which fails due to operator precedence.

Step-by-Step Explanation

  1. Input Validation

    • The function accepts obj, which may be:
    • an object
    • an array
    • a primitive If it’s not an object or array, recursion stops immediately.
  2. Looping Using for (var i in obj) the function scans every property.

  3. Key Validation It checks that:

    • the property is owned by the object
    • the value is an object/array worth recursing into
  4. Detecting the attributes Key When the function finds “attributes”, it identifies Salesforce metadata. Options:

    • delete it directly
    • store it in a debug/log array
  5. Recursion The function recurses into nested arrays and objects, ensuring deep cleaning.

A Better Version Using Modern JavaScript

A more modern, correct, and safe approach:

function removeAttributes(obj) {
    if (typeof obj !== 'object' || obj === null) return;

    for (const key in obj) {
        if (key === 'attributes') {
            delete obj[key];
            continue;
        }
        removeAttributes(obj[key]);
    }
}