backbone-nested icon indicating copy to clipboard operation
backbone-nested copied to clipboard

changedAttributes return entire deep object instead of only the changed field

Open ericchaves opened this issue 12 years ago • 9 comments

Hi there,

After updating a sub-set of nested properties, calling model.changedAttributes will return the entire object instead of only the changed ones.

var book = new Backbone.NestedModel.model({
    title: 'abook',
    author: {
        first_name: 'Jane',
        last_name: 'Doe'
    },
    category: 'Mistery'
});
book.save();
...
book.set({
    title: 'TheBook',
    author: {
        first_name: 'Jhon'
    }
});
console.log(book.changedAttributes());
/* printed result is
{ 
    title: 'TheBook',
    author: {
        first_name: 'Jhon',
        last_name: 'Doe'
    }
}
*/

Would it be possible to just return the changedAttributes?

ericchaves avatar Feb 20 '13 19:02 ericchaves

Mind submitting a failing test?

afeld avatar Feb 20 '13 19:02 afeld

Hi Aidan,

I was going through your test cases so I could write one but I got a little confused about what your implementation of changedAttributes actually works. I'm not very familiar with qunit so I may had misunderstood the tests. Please forgive me if so.

From Backbone docs, changedAttributes should return only the changed fields, to be used, for example, in partial updates and partial syncs (by PATCHing an objetc).

Hence, assuming your test case scenario (and it's doc object) when we do an update, say doc.set({'name.middle.full': 'Limburger'});, a call to changedAttributes (assuming no previous updates was done in the doc) should return exactly that, right?

But according to your tests, the changedAttributes returns a hash composed by the actual object plus other path's variants (test case 99, "#changedAttributes() should return the attributes for the full path and all sub-paths", line 647 of nested-model.js).

Also when I run my sample code, I got a totally different object from your tests. What I got seems to be a hash of all nested object that have any attributes changed (which is more than the expect hash of changed attributes only).

I'm sure I'm missing something here, but I can't got what it is. Would you care explaining what a call to NestedModel.changedAttributes returns?

Thanks for the help,

Eric

ericchaves avatar Feb 22 '13 14:02 ericchaves

I'm having this problem as well. changedAttributes correctly returns "false" when no fields have changed. But when I change a single field, changeAttributes returns the entire object.

jabbett avatar Mar 28 '13 15:03 jabbett

Again, a pull request with a test case that can be worked against would be super helpful. Thanks!

afeld avatar Mar 28 '13 15:03 afeld

Thanks for the motivation, I finally cracked open the test suite! It turns out that I'm seeing this problem because I'm using Backbone 0.9.9, not 0.9.2. Do you plan to support 0.9.9 or 1.0 soon?

jabbett avatar Mar 28 '13 18:03 jabbett

Ah, gotcha. See #72.

afeld avatar Mar 28 '13 18:03 afeld

Backbone 1.x (and 0.9.9) support has landed in master. Can you retest and see whether this is still a problem?

gkatsev avatar Jan 11 '14 03:01 gkatsev

Still happens with backbone 1.1.0 and backbone-nested 2.0.0

alebedev avatar Apr 15 '14 09:04 alebedev

Here's naive solution in coffeescript that I'm using as workaround


        changedAttributes: ->
          changes = super

          getPreviousValue = (attrPath) =>
            value = _.clone(this._previousAttributes)
            for key in attrPath.split('.')
              value = value?[key]
            value

          flatChanges = (changes, path) ->
            result = {}
            for key, value of changes
              attrPath = _.compact([path, key]).join('.')
              unless _.isObject(value)
                unless value == getPreviousValue(attrPath)
                  result[attrPath] = value
              else
                _.extend(result, flatChanges(value, attrPath))
            result
          result = flatChanges(changes)
          result     

alebedev avatar Apr 15 '14 09:04 alebedev