Senthe Senthe - 1 year ago 75
Javascript Question

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

I have a

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
model in inputs, change some values inside.
doesn't change. Then I want to send via
all the changes made, but not the fields which were not changed. So I need to strip the
from all fields that are the same in unchanged

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.

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.

Answer Source

This is what I ended up with. Maybe it'll help someone. I used DeepDiff library. Code is in CoffeScript, should be easy to translate to 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 + "."
            formattedPath += pathPart
        changes[formattedPath] = editable[formattedPath]