How to cross a 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 am creating a deep copy using the JSON trick:

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

Then I use the editableItem model in the inputs, change some values ​​inside. selectedItem does not change. Then I want to send through PATCH all the changes made, but not the fields that have not been changed. Therefore, I need to remove editableItem from all fields that are the same in unchanged selectedItem .

How to do it efficiently? I was thinking of traversing an object recursively using Underscore, but I would really like to know whether it is good to think before I solve it.

Alternatively, I could create a third object that will contain only indirect fields from the second, added dynamically, but I'm not sure how to approach this.

Editorial: To be clear, I expect the answer to be general and suppose that the most complex structure of the object is possible. For example, there are no answers from this question , because they either assume that the object has only simple fields, or they must have an Angular observer explicitly set for each field separately.

+6
source share
2 answers

Here is what I ended up with. Maybe this will help someone. I used the DeepDiff library. Code in CoffeScript should be easy to translate into JavaScript if anyone needs it.

  $scope.getChangesObject = () -> selected = $scope.selectedItem editable = $scope.editableItem changes = {} differences = DeepDiff(selected, editable) for diff in differences formattedPath = "" for pathPart, index in diff.path if index isnt diff.path.length - 1 formattedPath += pathPart + "." else formattedPath += pathPart changes[formattedPath] = editable[formattedPath] changes 
0
source

I am doing 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 it will bring you here. I do not use it in any scenarios where the objects have member objects or arrays, but you should be able to check if the "prop" is an object or an array and call it recursively. The biggest caveat I see in this approach is that if you have a deep nested structure, you cannot detect changes until you go down a few levels. You may have to save the full potential hierarchy for the changed property in memory, and then when you discover the change at a lower level, write the entire hierarchy to the output object.

+1
source

All Articles