recursionecmascript-6salesforcelwcaura.js

Aura to LWC recursion method migration


I have an older Aura method here that I want to translate to modern Javascript. For some reason I keep getting different output. I console log before recursion (data), then I console log before the getFieldNames() function and the "cur" is different. If I log 'cur' at the very beginning, it is also different. I basically expect the Logs for AURA and LWC to be the same but LWC only has one.

Thoughts: My goals is to get the nested object value, but it feels like they over engineered it. It may be as simple as dot notation and then looping over that object. It just feels weird.

  let test = data.ContactTerritoryRelationship__c.Contact__r;
        Object.keys(test).forEach(function (prop) {
            console.log(test[prop]);
        })

AURA

  formatNestedMetadata: function (data) {
        let result = [];
        let helper = this;
      
        function recurse(cur, prop, attr) {
            if (cur.hasOwnProperty("__attr__")) {
                attr = cur["__attr__"];
                delete cur["__attr__"];
            }
            for (let key of Object.keys(cur)) {
                let value = cur[key];
                if (typeof value != "object") {
                    // Our value is not an attribute, so stop recursing
                    cur["apiName"] = prop;
                    if (attr) {
                        cur["object"] = attr["sObjectType"];
                        if (prop.includes("Contact__r")) {
                            cur["label"] = attr["label"] == "Account ID" ? "Firm" : "" + 
                            attr["label"];
                        } else {
                            cur["label"] = attr["label"];
                        }
                    } else {
                        cur["object"] = prop.includes("Contact__r")
                            ? "Contact"
                            : "distributionterritory__c";
                        if (prop.includes("Contact__r")) {
                            **console.log('Aura', cur);**
                            cur["label"] = helper.getFieldName(cur["label"]);
                        } else {
                            cur["label"] = cur["label"];
                        }
                    }
                    result.push(cur);
                    break;
                } else if (Array.isArray(value)) {
                    // Pass
                } else {
                    // True if value is object
                    let newProp = prop && key ? prop + "." + key : key;
                    recurse(cur[key], newProp, attr);
                }
            }
        }
        recurse(data, "");
        return result;
    },

LWC Version

formatNestedMetadata(data) {
        let result = [];
        console.log(data);
        //DATA MATCHES AURA VERSION UP UNTIL THIS POINT...

        function recurse(cur, prop, attr) {
            if (Object.prototype.hasOwnProperty.call(cur, "__attr__")) {
                attr = cur.__attr__;
                delete cur.__attr__;
            }

            for (let key of Object.keys(cur)) {
                let value = cur[key];
                if (typeof value != "object") {
                    // Our value is not an attribute, so stop recursing
                    cur.apiName = prop;
                    if (attr) {
                        cur.object = attr.sObjectType;
                        if (prop.includes("Contact__r")) {
                            cur.label = attr.label === "Account ID" ? "Firm" : "" + attr.label;
                        } else {
                            cur.label = attr.label;
                        }
                    } else {
                        cur.object = prop.includes("Contact__r")
                            ? "Contact"
                            : "distributionterritory__c";
                        if (prop.includes("Contact__r")) {
                            **console.log('LWC', cur);**<-----------This logs differently now?
                            cur.label = this.getFieldName(cur.label);
                        } else {
                            // is this doing anything..
                            cur.label = cur.label;

                        }

                    }
                    break;
                } else if (Array.isArray(value)) {
                    // Pass
                } else {
                    // True if value is object
                    let newProp = prop && key ? prop + "." + key : key;
                    recurse(cur[key], newProp, attr);
                }
            }
        }
        recurse(data, "");
        return result;
    }

PICTURES OF OUTPUT Console Logs


Solution

  • The lines let helper = this; and cur["label"] = helper.getFieldName(cur["label"]); in the AURA method save the this in a closure for the recurse function to use.

    The LWC version needs to use the same approach. The this in the LWC recurse is no longer set properly.

    Hard to validate this suggestion without reconstructing your environment, but seems like a starting point.

    Finally, I agree, there should be an easier way. Does seem over-engineered.