awd2923
awd2923

Reputation: 23

AngularJs - How can I filter through a nested array object in each iteration within ng-repeat?

I have following object in my controller.

function MyCntrl($scope) {
  $scope.colors = [
    {name:'black', shade:'dark',variant:['metal','pure','knight']},
    {name:'white', shade:'light',variant:['pure','knight']},
    {name:'red', shade:'dark',variant:['metal','pure']},
    {name:'blue', shade:'dark',variant:['metal','knight']},
    {name:'yellow', shade:'light',variant:['chrome','silver','knight']}
  ];
}

Two questions.

1.How can I create a select box with 'variant' array in each object without duplication? Is this possible with ng-options? I'm looking for this -

   <select ng-model="selectedVariant">
    <option>Metal</option>
    <option>Pure</option>
    <option>Knight</option>
    <option>Chrome</option>
    <option>Solver</option>
   </select>
  1. How can I apply filter to each variant array when using ng-repeat? I tried following

<div ng-controller="MyCntrl">
      <select ng-model="selectedVariant" ng-options="variant for variant in (c.variant for c in colors)"></select><br>
      <ul>
        <li ng-repeat="c in colors | filter:{c.variant:selectedVariant}">{{c.name}}</li>
      </ul>
</div>

Upvotes: 0

Views: 235

Answers (1)

raina77ow
raina77ow

Reputation: 106365

For the first question, you can either write a specific function that returns only unique values of all variants merged together or calculate this value just once (as your list of colors seems to be static). You can easily transform from one to another. For example:

 $scope.allVariants = function(colors) {
    return colors.reduce(function(variants, color) {
      color.variant.forEach(function(variant) {
        if (variants.indexOf(variant) === -1) {
          variants.push(variant);
        }
      });
      return variants;
    }, []);
  }($scope.colors);

For the second, I'd go with a custom filter function. It's quite trivial:

$scope.hasSelectedVariant = function(color) {
    return color.variant.indexOf($scope.selectedVariant) !== -1;
};

Now this is how those can be used in the template:

<div>
   <select ng-model="selectedVariant" ng-options="variant for variant in allVariants"></select><br>
   <ul>
     <li ng-repeat="c in colors | filter:hasSelectedVariant">{{c.name}}</li>
   </ul>
</div>

Plunkr demo.

Upvotes: 1

Related Questions