diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 34d32f59adb2..74faed3ae5a4 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -175,8 +175,16 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) { return trackByExpGetter($scope, hashFnLocals); }; } else { - trackByIdFn = function(key, value) { - return hashKey(value); + trackByIdFn = function(key, value, index) { + var valType = typeof value; + + // if value is a primitive and key != index (case for arrays) + // then append key to value to ensure uniqueness for identical values + if(valType != 'object' && !(typeof key === 'number' || key === index)) { + return hashKey(key + ':' + value); + } else { + return hashKey(value); + } } } diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index ac6ceb830f2e..a84a8bcd72b0 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -85,6 +85,15 @@ describe('ngRepeat', function() { expect(element.text()).toEqual('misko:swe|shyam:set|'); }); + it('should iterate over an object/map with identical values', function() { + element = $compile( + '')(scope); + scope.items = {age:20, wealth:20, prodname: "Bingo", dogname: "Bingo", codename: "20"}; + scope.$digest(); + expect(element.text()).toEqual('age:20|codename:20|dogname:Bingo|prodname:Bingo|wealth:20|'); + }); describe('track by', function() { it('should track using expression function', function() {