pbordeaux
pbordeaux

Reputation: 465

Filtering object in ng-repeat: keys (not value) against items in an array on scope

I want to filter four divs based on whether or not a trait of the divs, called 'type', appears in an array on the scope. Below please find a more detailed explanation and the 3 ways I tried to accomplish this goal:

I have four buttons that when clicked should toggle four different divs which are the byproduct of an ng-repeat

buttons:

 <div class="buttonDiv">
        <ul>
        <li ng-repeat="type in vm.reviewTypes">
          <span ng-click="vm.toggleTypes.indexOf(type) == - 1 ? vm.toggleTypes.push(type) : vm.toggleTypes.splice(vm.toggleTypes.indexOf(type), 1)" ng-class="{ 'activeCategoryButton' : vm.toggleTypes.indexOf(type) != -1}">{{type}}</span>
        </li>
      </ul>
    </div>

The buttons are built off an ng-repeat through an array, vm.reviewTypes, which contains ['type1','type2','type3','type4']

An array is built on the scope called vm.toggleTypes that contains the 'type' assigned to the current active button which is also the div(s) I want shown.

Here is the div (well technically footer) with the ng-repeat (HTML BEFORE I TRIED TO FILTER):

    <footer ng-repeat="(kind, reviews) in vm.reviews" class="site-footers-container {{kind}}">
    <span>{{ kind }}</span>
 //MORE THINGS HERE............
  </footer>

I want to filter based off of the 'kind' matching an element of the array vm.toggleTypes whose content is based off of which buttons are active. I have tried the following:

(ATTEMPT 1)

      <footer ng-repeat="(kind, reviews) in vm.reviews | vm.toggleTypes.indexOf(kind) != -1" class="site-footers-container {{kind}}">
    <span>{{ kind }}</span>
 //MORE THINGS HERE............
  </footer>

the above gvies me "Unknown provider: vmFilterProvider" as the error, reference

next I tried:

(ATTEMPT 2)

          <footer ng-repeat="(kind, reviews) in vm.reviews | filter: vm.toggleTypes.indexOf(kind) != -1" class="site-footers-container {{kind}}">
    <span>{{ kind }}</span>
 //MORE THINGS HERE............
  </footer>

No errors here, however, it just doesn't work.

I have also tried making a function on the scope that simply returns true or false depending on if the key, 'kind', from the ng-repeat matches one of the entries in the array vm.toggleTypes; however, this gave me the same error 'Unknown provider: vmFilterProvider' and the function in the controller was:

(ATTEMPT 3)

vm.matchClass = function (key) {
if (vm.toggleTypes.indexOf(value) != -1)
{return true;}
else {return false;}
};

my html was then:

          <footer ng-repeat="(kind, reviews) in vm.reviews | vm.matchClass(kind)" class="site-footers-container {{kind}}">
    <span>{{ kind }}</span>
 //MORE THINGS HERE............
  </footer>

Sorry in advance, am new to Angular and have not used filters many times

Upvotes: 2

Views: 652

Answers (3)

PandaScript
PandaScript

Reputation: 55

According to Angular's documentation, you can't use the built in filters 'filter' and 'orderBy' when using ng repeat to iterate over an object.

Upvotes: 0

pbordeaux
pbordeaux

Reputation: 465

Instead of trying to use the | filtering, use an ng-if that evaluates whether or not the current 'key' of the object being iterated over is in the array on the scope:

<footer ng-repeat="(kind, reviews) in vm.reviews" ng-if="vm.toggleTypes.indexOf(kind) != -1" class="site-footers-container {{kind}}">
<span>{{ kind }}</span>
//MORE THINGS HERE............
 </footer>

Works perfectly

Upvotes: 0

Brent Washburne
Brent Washburne

Reputation: 13138

I would just split the original list into the four desired lists in the controller. That way the filtering is done only once and the ng-repeat is much faster.

Upvotes: 1

Related Questions