Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter array of objects by attribute with integer value in ng-repeat

I have the directive like this

ng-repeat="place in tb_places | filter:{'id':inputID}"

to output some array of objects looks like this

$scope.tb_places = [
{name: 'some1', id:1}
...
{name: 'some10', id:10}
{name: 'some11', id:11}
{name: 'some12', id:12} 
...
]

when i change the inputID and set it equal to 1, the result array fills with elements of source array with 'ids' of 1 and 10,11,12. Thus, the part of 'id' value is checked like substrings, not a numbers. How can i cure it?

thanks!

UPD i've tried to add ":true" in filter expression - it completely clears output (result array), It works for a simple array of strings, but not the objects ("true" wants exact match with pattern object, it means with all its properties)

SOLVED!!!

Sorry guys, my fault! 'inputID' was not the same type, as 'id' (string vs int), so built-in comparator (":true") returns false. Many thanks!

ps sorry, i can't vote for you answers - lack of reputation ... see you!

like image 536
georgiy.zhuravlev Avatar asked Apr 24 '15 14:04

georgiy.zhuravlev


People also ask

How do I filter items in NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.

How do I get an index value in ng-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

Can we use filter in NG-model?

By setting the ng-model directive on an input field, we can use the value of the input field as an expression in a filter.


3 Answers

You need to add the comparator as per the angular filter to achieve your requirement.

Can you change the code as:

ng-repeat="place in tb_places | filter: {'id' : inputID} : true"
like image 69
Arulkumar Avatar answered Oct 27 '22 09:10

Arulkumar


You'll need to either supply your own comparator or manually convert the queried against value to an integer and use the true flag:

Controller:

app.controller('DemoCtrl', function() {
  this.query = '1';

  this.queryAsInt = function() {
    return parseInt(this.query, 10);
  };

  this.stuff = [
    {id: 1, label: 'Foobar 1'},
    {id: 2, label: 'Foobar 2'},
    {id: 3, label: 'Foobar 3'},
    {id: 4, label: 'Foobar 4'},
    {id: 5, label: 'Foobar 5'},
    {id: 6, label: 'Foobar 6'},
    {id: 7, label: 'Foobar 7'},
    {id: 8, label: 'Foobar 8'},
    {id: 9, label: 'Foobar 9'},
    {id: 10, label: 'Foobar 10'},
    {id: 11, label: 'Foobar 11'},
    {id: 11, label: 'Foobar 12'}
  ];

  this.compare = function(a, b) {
    return parseInt(a, 10) === parseInt(b, 10);
  };
});

View:

<div ng-controller="DemoCtrl as demo">
  <input ng-model="demo.query">
  <p>With custom comparator:</p>
  <ul>
    <li ng-repeat="item in demo.stuff | filter:{id:demo.query}:demo.compare">
      {{item.label}}
    </li>
  </ul>

  <p>With type casting:</p>
  <ul>
    <li ng-repeat="item in demo.stuff | filter:{id:demo.queryAsInt()}:true">
      {{item.label}}
    </li>
  </ul>
</div>);

And here's a running example: http://jsbin.com/kecihexeyu/1/edit?html,js,output

like image 26
jtrussell Avatar answered Oct 27 '22 08:10

jtrussell


Write your own comparator.

HTML

<li ng-repeat="place in tb_places | filter:{'id':inputID}: filterId">{{place.id}}</li>

Javascript

filterId = function(actual, expected) {
    return actual == expected;
}

Plunker full version. http://plnkr.co/edit/3JEvThiemq8ro8cXCYBd?p=preview

like image 1
hutingung Avatar answered Oct 27 '22 09:10

hutingung