diff --git a/src/plugins/nested-dirty.js b/src/plugins/nested-dirty.js index 16cb8d3..becdd0f 100644 --- a/src/plugins/nested-dirty.js +++ b/src/plugins/nested-dirty.js @@ -8,6 +8,10 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restmod) { + function isPlainObject(_val) { + return angular.isObject(_val) && !angular.isArray(_val); + } + function copyOriginalData(_from) { var Model = _from.$type, result = {}; @@ -38,7 +42,7 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm _original = navigate(_original, _keys); if(_original.hasOwnProperty(prop)) { - if(_comparator && typeof _comparator === 'function') { + if(typeof _comparator === 'function') { isDirty = !!_comparator(_model[prop], _original[prop]); } else { isDirty = !angular.equals(_model[prop], _original[prop]); @@ -54,8 +58,7 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm if(_original) { for(var key in _original) { if(_original.hasOwnProperty(key)) { - // isObject returns true if value is an array - if(angular.isObject(_original[key]) && !angular.isArray(_original[key])) { + if(isPlainObject(_original[key]) && isPlainObject(_model[key])) { childChanges = findChangedValues(_model[key], _original[key], _keys.concat([key]), _comparator); changes.push.apply(changes, childChanges); } else { diff --git a/test/plugins/nested-dirty-spec.js b/test/plugins/nested-dirty-spec.js index 4cf1e20..ed749d7 100644 --- a/test/plugins/nested-dirty-spec.js +++ b/test/plugins/nested-dirty-spec.js @@ -30,12 +30,12 @@ describe('Plugin: Nested Dirty Model', function() { it('should list changes on nested objects', function() { bike.brandName = 'BMX'; expect(bike.$dirty()).not.toContain('customisations.wheels'); - + bike.customisations.wheels = 3; bike.colours.frame = 'green'; expect(bike.$dirty()).toContain('customisations.wheels'); expect(bike.$dirty()).toContain('colours.frame'); - + bike.customisations.seat.material = 'leather'; expect(bike.$dirty()).toContain('customisations.seat.material'); }); @@ -47,6 +47,11 @@ describe('Plugin: Nested Dirty Model', function() { expect(bike.$dirty()).toContain('stickers'); }); + it('should detect missing objects', function() { + bike.customisations = null; + expect(bike.$dirty()).toContain('customisations'); + }); + it('should compare with comparator function', function() { bike.customisations.wheels = 3; expect(bike.$dirty('customisations.wheels', function (newVal, oldVal) {