Search code examples
javascriptangularjsangular-ui-select

Remove duplicates from ui-select choices when using another data source for default selected


Ok, I know this has been covered before and I've tried all those results but can't get them to work in my situation:

I'm trying to use angular ui-select with multiple data sources - one for default choices and another for selectable options but no dupes should occur

For example:

for the ng-model binding, I am using an empty array on the $scope that gets populated with categories associated with the post from an API endpoint called "categories".

For the default selected choices, I'm getting categories already associated with the post object - this comes from another api endpoint.

My Controller

app.controller('MainCtrl', function($scope, $http) {

    $scope.selectedTerms = [];

$http.get('currentTerms.json').then(function(currentTermsObj){

    var currentTerms = currentTermsObj.data;

        currentTerms.map(function(currentTerm){

        var currentPostTerm = currentTerm;

        $scope.selectedTerms.push(currentPostTerm); 
        });
  });



$http.get('possibleTerms.json').then(function(possibleTermsObj){

  $scope.possibleTerms = possibleTermsObj.data;

  });

My HTML:

    <ui-select
        multiple
        ng-model="selectedTerms">
        <ui-select-match placeholder="Select Category...">{{$item.name}}</ui-select-match>
        <ui-select-choices
            repeat="term in possibleTerms">
        {{term.name}}
        </ui-select-choices>
    </ui-select>

The problem is, no matter what I do, there's always duplicates and angular freaks out with the following error:

"Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys."

oh and I've tried using "track by $index" but no luck.

How do I use two different data sources and get ui-select to remove duplicates from the choices dropdown when they're already present from another data source?

Plnkr demonstrating my issue: http://plnkr.co/edit/WDthr7?p=preview


Solution

  • An alternative way is to merge them by yourself. see http://plnkr.co/edit/NPdxYK8fqCPMhsKXRSGH?p=preview

    In the controller: -

    $http.get('currentTerms.json').then(function(currentTermsObj){
    
        var currentTerms = currentTermsObj.data;
    
            currentTerms.map(function(currentTerm){
    
            var currentPostTerm = currentTerm;
    
            $scope.selectedTerms.push(currentPostTerm); 
            });
    
            $http.get('possibleTerms.json').then(function(possibleTermsObj){
    
                $scope.possibleTerms = possibleTermsObj.data;
                for(var i = 0; i < $scope.possibleTerms.length; i++){
                  if(i < $scope.selectedTerms.length){
    
                  $scope.possibleTerms[i] = $scope.selectedTerms[i];
                }
             }   
          });
      });
    

    please note that the above merging logic works only for this example for time saving.