Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to traverse JS object and all arrays and objects inside to compare it with its copy?

I have a selectedItem object in Angular, it contains other objects and arrays. I create a deep copy using a JSON trick:

$scope.editableItem = JSON.parse(JSON.stringify($scope.selectedItem))

Then I use editableItem model in inputs, change some values inside. selectedItem doesn't change. Then I want to send via PATCH all the changes made, but not the fields which were not changed. So I need to strip the editableItem from all fields that are the same in unchanged selectedItem.

How to do this efficiently? I was thinking about traversing object recursively using Underscore, but I'd really like to know if it's a good way of thinking before I tackle it.

Alternatively I could probably create third object which would only contain touched fields from the second one, added dynamically, but I'm not sure how to approach this.

EDITED: To be clear, I expect the answer to be generic and assume the most complicated object structure possible. For example no answers from this question are applicable here as they either assume the object has only simple fields or they need to have Angular watcher explicitly set for every field separately.

like image 872
Senthe Avatar asked May 09 '16 13:05

Senthe


People also ask

How do you iterate through an array of objects?

To iterate through an array of objects in JavaScript, you can use the forEach() method aong with the for...in loop. The outer forEach() loop is used to iterate through the objects array.

Can I use forEach on object?

JavaScript's Array#forEach() function lets you iterate over an array, but not over an object. But you can iterate over a JavaScript object using forEach() if you transform the object into an array first, using Object. keys() , Object. values() , or Object.


1 Answers

I do something similar with a function like this:

function getUpdateObject(orig, current) {
    varChanges = {};

    for (var prop in orig) {
        if (prop.indexOf("$") != 0 && orig[prop] !== current[prop]) {
            varChanges[prop] = current[prop];
        }
    }
    return varChanges ;
};

I don't think this will get you all the way there. I'm not using it in any scenarios where the objects have member objects or arrays, but you should be able to test if "prop" is an object or array and call it recursively. The biggest caveat I see to that approach is if you have a deep, nested structure, you may not detect a change until you're down several levels. You'd probably have to keep the full potential hierarchy for a changed property in memory, then when you detect a change at a lower, level, write the whole hierarchy to the output object.

like image 96
Mike Feltman Avatar answered Sep 24 '22 15:09

Mike Feltman