"Duplicates in a repeater are not allowed" on ng-repeat

All we need is an easy explanation of the problem, so here it is.

I’ve got the following json data returned from a service request:

{
    "entries": [{
        "id": 2081,
        "name": "BM",
        "niceName": "bodmas"
        }]
    }, {
        "id": 8029,
        "name": "Mas",
        "niceName": "Masm"
        }]
    }],
    "count": 2
}

And I am trying the following code in html to loop through this data:

<option ng-repeat="entry in entries" value="{{entry.name}}">{{entry.name}}</option>

I get the following error when I run the code:

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: entry in entries, Duplicate key: string:c

Following is the code for my controller:

myApp.controller("MyController", ['$scope', '$http', '$log', function($scope, $http, $log){
       ...

       $http.get('https://myServiceURL').success(function(data){
                    $scope.entries = data;
        });
}]);

Could somebody help me understand why am I getting that error?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Add track by $index to your ng repeat so instead of:

<option ng-repeat="entry in entries" value="{{entry.name}}">{{entry.name}}</option>

Try:

<option ng-repeat="entry in entries track by $index" value="{{entry.name}}">{{entry.name}}</option>

There’s further information about this in
the documentation for this error message:

Occurs if there are duplicate keys in an ngRepeat expression.
Duplicate keys are banned because AngularJS uses keys to associate DOM
nodes with items.

By default, collections are keyed by reference which is desirable for
most common models but can be problematic for primitive types that are
interned (share references).

Method 2

Your JSON is invalid and should be :

{
    "entries": [{
        "id": 2081,
        "name": "BM",
        "niceName": "bodmas"
    }, {
        "id": 8029,
        "name": "Mas",
        "niceName": "Masm"
    }],
    "count": 2
}

Also, make sure you are accessing the document at the right level, use :

$http.get('https://myServiceURL').success(function(data){
    $scope.entries = data.entries;
});

Then, it should work. See this JSBin.

Method 3

If I may add an additional reason as to why this can occur…

If you are doing this with a JS object [] or {}

and you are passing it in to a directive like this

<my-directive my-attribute="{{ myObject }}"></my-directive>

Inside the directive you must turn myObject back into an object by doing this

...
controller: function( $scope ){

  $scope.links = $scope.$eval( $scope.myObject );
....

Then the HTML and ng-repeat will work

...
<span class="" ng-repeat="link in links">
...

ngRepeat does not know how to repeat over a single string.

Here is what the object would look like before $scope.$eval

"[{ hello: 'you' }]"

and after $scope.$eval()

[{ hello: 'you' }] an actual object to repeat over.

The error kind of makes a reference that it cannot repeat of a string. Here is the error that I got.

Error: [ngRepeat:dupes] http://errors.angularjs.org/1.3.0-beta.8/ngRepeat/dupes?p0=link%20in%20links&p1=string%3Al

Method 4

It looks like you have a problem with the structure of the data in your scope. Your example JSON shows an object with an entries property and a count property. You then put that whole object in your scope as entries. This means you’d need to access the entries as entries.entries, with the count in entries.count. Perhaps this controller is closer to what you wanted:

myApp.controller("MyController", ['$scope', '$http', '$log', function($scope, $http, $log){
    ...

    $http.get('https://myServiceURL').success(function(data){
        $scope.entries = data.entries;
        $scope.count = data.count;
    });
}]);

Method 5

// To allow this Web Service to be called from script, using ASP.NET AJAX,uncomment the following line.

[System.Web.Script.Services.ScriptService] ==> Uncomment this line If you use .NET Service

Method 6

duplicates in In ng-repeat is not allowed .
Example

    <!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="angular.js"></script>

</head>
<body>
    <div ng-app="myApp" ng-controller="personController">
        <table>
            <tr> <th>First Name</th> <th>Last Name</th> </tr>
            <tr ng-repeat="person in people track by $index">
                <td>{{person.firstName}}</td>
                <td>{{person.lastName}}</td>
                <td><input type="button" value="Select" ng-click="showDetails($index)" /></td>
            </tr>

        </table> <hr />
        <table>
            <tr ng-repeat="person1 in items track by $index">
                <td>{{person1.firstName}}</td>
                <td>{{person1.lastName}}</td>
            </tr>
        </table>
        <span>   {{sayHello()}}</span>
    </div>
    <script> var myApp = angular.module("myApp", []);
        myApp.controller("personController", ['$scope', function ($scope)
        { 
            $scope.people = [{ firstName: "F1", lastName: "L1" },
                { firstName: "F2", lastName: "L2" }, 
                { firstName: "F3", lastName: "L3" }, 
                { firstName: "F4", lastName: "L4" }, 
                { firstName: "F5", lastName: "L5" }]
            $scope.items = [];
            $scope.selectedPerson = $scope.people[0];
            $scope.showDetails = function (ind) 
            { 
                $scope.selectedPerson = $scope.people[ind];
                $scope.items.push($scope.selectedPerson);
            }
            $scope.sayHello = function ()
            {
                return $scope.items.firstName;
            }
        }]) </script>
</body>
</html>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply