38

I have a simple ng-repeat that throws out data, one of fields it displays is NumberOfStamps:

<tr ng-repeat-start="list in Data.Items ">
   <td><a href=" {[{list.Title}]} {[{list.ForeName}]} {[{list.SurName}]}</a></td>
   <td>(Date of Birth {[{list.Dob}]})</td>
   <td>{[{list.NumberOfStamps}]}  stamps</td>
</tr>

Example output:

Mr Adam Happy  Date of Birth 01/6/1984     16 stamps
Mr Adam Sad    Date of Birth 24/11/1975    0 stamps
Mr Adam Green  Date of Birth 02/1/1963     1 stamps
Mr Adam Red    Date of Birth 21/1/1951     12 stamps
Mr Adam Blue   Date of Birth 28/10/1998    0 stamps
Mr Adam Brown  Date of Birth 25/9/2010     0 stamps
Mr Adam Black  Date of Birth 24/8/1954     21 stamps
Mr Adam Violet Date of Birth 17/5/1942     54 stamps

How can i modify this ng-repeat to only show records where the NumberOfStams is > 0? I've tried:

<tr ng-repeat-start="list in Data.Items | filter:{NumberOfStamps > 0}">
   <td><a href=" {[{list.Title}]} {[{list.ForeName}]} {[{list.SurName}]}</a></td>
   <td>(Date of Birth {[{list.Dob}]})</td>
   <td>{[{list.NumberOfStamps}]}  stamps</td>
</tr>

Expected output:

Mr Adam Happy  Date of Birth 01/6/1984     16 stamps
Mr Adam Green  Date of Birth 02/1/1963     1 stamps
Mr Adam Red    Date of Birth 21/1/1951     12 stamps
Mr Adam Black  Date of Birth 24/8/1954     21 stamps
Mr Adam Violet Date of Birth 17/5/1942     54 stamps
John Slegers
  • 45,213
  • 22
  • 199
  • 169
Oam Psy
  • 8,555
  • 32
  • 93
  • 157

5 Answers5

81

Create a predicate function on the relevant scope:

$scope.greaterThan = function(prop, val){
    return function(item){
      return item[prop] > val;
    }
}

As a first argument, it takes a property name on the object. The second argument is an integer value.

Use it in your view like this:

<tr ng-repeat-start="list in Data.Items | filter: greaterThan('NumberOfStamps', 0)">

Demo

OXMO456
  • 3,558
  • 2
  • 25
  • 35
Marc Kline
  • 9,399
  • 1
  • 33
  • 36
  • Thanks for the post and link, whats the benefit of using/creating a predicate over other people solutions? – Oam Psy Jun 06 '14 at 12:16
  • 1
    The solution is best expressed as a *filter*, close to what you originally tried. One answer currently posted is not a filter, and the other only negates 0 values - it doesn't do a greater than comparison. – Marc Kline Jun 06 '14 at 12:20
  • I understand your comments, and your code is neat and simple.. Only reason i questioned it because i 'expected' Angular to have a 'one or two word' way of doing it. – Oam Psy Jun 06 '14 at 12:40
  • 1
    I was trying to wonder how to do conditionals in filter. And this helped me alot. :) – Bruno Gomes Sep 05 '14 at 15:02
  • This solution is very elegant; thank you very much. Just learned a better way to do something. – Amir Mog Mar 25 '17 at 19:57
44

You can create a filter with ng-if like this:

<li ng-repeat="seller in sellers" ng-if="seller.sales > 0" >{{ seller.name }}</li>
Ciro Mine
  • 819
  • 8
  • 15
  • I personally prefer this approach rather than using the filters as it gives a bit more flexibility. – Dan Atkinson Apr 04 '16 at 15:31
  • 5
    This is easy to implement but becomes annoying when we rely on ng-repeat $index integrity, for example if $first / $last / etc doesn't have seller.sales then we can't apply special markup which is a common use case for me. – irth Jul 05 '16 at 23:47
  • I know this approach is better than creating a custom filter.Now how can I get the count of sellers after ng-if applied in template? – Mayank Patel Nov 08 '17 at 06:00
2
<tr ng-repeat-start="Data.Items in list = ( Data.Item | filter:{NumberOfStamps : !0}">
   <td><a href=" {[{list.Title}]} {[{list.ForeName}]} {[{list.SurName}]}</a></td>
   <td>(Date of Birth {[{list.Dob}]})</td>
   <td>{[{list.NumberOfStamps}]}  stamps</td>
</tr>
Dinesh ML
  • 921
  • 11
  • 15
1

One possible way would be to remove the items that do not meet the criterai from the DOM using ng-if

<tr ng-repeat-start="list in Data.Items ">
    <td ng-if="list.NumberOfStamps > 0"><a href=" {[{list.Title}]} {[{list.ForeName}]} {[{list.SurName}]}</a></td>
    <td ng-if="list.NumberOfStamps > 0">(Date of Birth {[{list.Dob}]})</td>
    <td ng-if="list.NumberOfStamps > 0">{[{list.NumberOfStamps}]}  stamps</td>
</tr>

Because you cannot have a div in a tr you have to ng-if the td's seperately, which is not optimal if you have alot of td's

Community
  • 1
  • 1
Tim
  • 41,901
  • 18
  • 127
  • 145
0

Take a look at this stack overflow answer. AngularJS - How to structure a custom filter with ng-repeat to return items conditionally it clearly explains how to create a custom angular filter for use with ng-repeat. Once you understand this you will be able to filter out basically anything from an ng-repeat!

Community
  • 1
  • 1
Benjamin Conant
  • 1,684
  • 1
  • 14
  • 17