Elvis Reis
Elvis Reis

Reputation: 305

Add element for object

I need to go through a list of objects to find the element and add a new element to the root, I can scroll through the list and find the element, but I can not add to the correct level

var data = [

    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    },
    {
        "id": 4,
        "children": [
            {
                "id": 6
            },
            {
                "id": 7                    
            }
        ]
    },
    {
        "id": 5
    }

];

function findById(data, id, element) {
    function iter(a) {
        if (a.id === id) {
            a.push(element); // ERROR
            result = a;
            return true;
        }
        return Array.isArray(a.children) && a.children.some(iter);
    }
    var result;
    data.some(iter);
    return result
}


var element = {
    "children": [{"id": 6}]
};

findById(data, 5, element);

document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');

https://jsfiddle.net/4nrsccnu/

Upvotes: 0

Views: 232

Answers (3)

Samuel Martins
Samuel Martins

Reputation: 46

The push function is used for arrays, not to object. Check for details https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push.

If you want to add a single keypair to your object, you can use Object.keys and Object.values. Like this:

function findById(data, id, element) {
    function iter(a) {
        if (a.id === id) {
            var key = Object.keys(element)[0];
            var value = Object.values(element)[0];
            a[key] = value;
            result = a;
            return true;
        }
        return Array.isArray(a.children) && a.children.some(iter);
    }

    var result;
    data.some(iter);
    return result;
}

Upvotes: 1

Chava Geldzahler
Chava Geldzahler

Reputation: 3730

You cannot push, because a is an object. However, you can simply add the desired property (in your case, children), and then assign it a value (in your case, the element).

var data = [

    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    },
    {
        "id": 4,
        "children": [
            {
                "id": 6
            },
            {
                "id": 7                    
            }
        ]
    },
    {
        "id": 5
    }

];

function findById(data, id, element) {
    function iter(a) {
        if (a.id === id) {
            a.children = element;  // Add property 'children'
            result = a;
            return true;
        }
        return Array.isArray(a.children) && a.children.some(iter);
    }
    var result;
    data.some(iter);
    return result
}

// remove property name from element, as that is being added in the function
var element = [
    {"id": 6}
];

findById(data, 5, element);

document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');

Upvotes: 1

Barmar
Barmar

Reputation: 780724

Use Object.assign to merge the properties from the element object to the current object of the iteration.

var data = [

    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    },
    {
        "id": 4,
        "children": [
            {
                "id": 6
            },
            {
                "id": 7                    
            }
        ]
    },
    {
        "id": 5
    }

];

function findById(data, id, element) {
    function iter(a) {
        if (a.id === id) {
            Object.assign(a, element);
            result = a;
            return true;
        }
        return Array.isArray(a.children) && a.children.some(iter);
    }
    var result;
    data.some(iter);
    return result
}


var element = {
    "children": [{"id": 6}]
};

findById(data, 5, element);

console.log(data);

Upvotes: 1

Related Questions