Skip to content
Advertisement

Searching nested object by property name and copying to new object does not result in all objects being copied

Link to TS Playground.

const data = {
    "cars": [
        {
            "name": "Audi",
            "color": "blue"
        },
        {
            "name": "Saab",
            "color": "red"
        },
        {
            "year": 2007,
            "owner": "NaN"
        }
    ],

    "boats": {
        "fish": [
            {
                "name": "Salmon",
                "safe": true
            }
        ],
        "sharks": {
            "name": "Great White"
        }
    },

    "trucks": {
        "vans": {
            "bikes": [1, 2, 3]
        }
    }
};

function findProperty(obj: any, property: string): any {
    let result:any = {};

   for(const prop in obj) {
        if(Object.prototype.toString.call(obj[prop]) === "[object Object]" && !obj[prop].hasOwnProperty(property)) 
            return findProperty(obj[prop], property);
        
        for(const i in obj[prop]) {
            if(obj[prop][i].hasOwnProperty(property)) {
                if(result.hasOwnProperty(prop)) {
                    result[prop].push(obj[prop][i]);
                } else {
                    Object.assign(result, {
                        [prop]: [obj[prop][i]]
                    });
                }
            }
        }
    }

    return result;
};

I’m trying to find all arrays with objects that contain the property name no matter how nested the initial data object is; and for some reason the final result only contains 1 result instead of all of them.

When I debug at line 45 with

console.log(obj[prop][i])

I can see that it finds all objects; all 3 of them, yet only one of them is present in the final result.

What am I missing here?

Answer

You keep making a new result object so you probably want to create it once and pass it along

function findProperty(obj: any, property: string, result: any = {}): any {

   for(const prop in obj) {
        if(Object.prototype.toString.call(obj[prop]) === "[object Object]" && !obj[prop].hasOwnProperty(property)) 
            return findProperty(obj[prop], property, result);
        
        for(const i in obj[prop]) {
            if(obj[prop][i].hasOwnProperty(property)) {
                console.log(obj[prop][i]);
                
                if(result.hasOwnProperty(prop)) {
                    result[prop].push(obj[prop][i]);
                } else {
                    Object.assign(result, {
                        [prop]: [obj[prop][i]]
                    });
                }
            }
        }
    }

    console.log("result:", result);
    return result;
};
Advertisement