Hack-R Hack-R - 2 months ago 25
Javascript Question

Filter object by child array in ng-repeat statement that uses track by $index to handle dupes

I have an object

narrow.searchedMenu
with 3 equal-length child arrays, which I display using
ng-repeat
with
track by $index
because there are some duplicate elements.

<ul>
<li ng-repeat="item in narrow.searchedMenu.description track by $index">
{{ narrow.searchedMenu.name[$index] }},
{{ narrow.searchedMenu.short_name[$index] }},
{{ narrow.searchedMenu.description[$index] }}</li>
</ul>


I need to be able to filter the displayed results by keeping only those results where a keyword appears in the
description
. If a
description
doesn't match I want to exlcude the
name
and
short_name
as well as the
description
.

Normally I would use something like this:

| filter{description:'chicken'}


appended to the end of the
ng-repeat
statement. However, it does not seem to work with
track by
.

It gives me this error on the console when I try it:


Error: [$parse:syntax]
http://errors.angularjs.org/1.5.8/$parse/syntax?p0=%7B&p1=is%20an%20unexpected%20token&p2=16&p3=NaNndex%20%7C%filter%7Bdescription%3A'chicken'%7D&p4=%7Bdescription%3A'chicken'%7D


I've tried several other potential solutions but so far no luck.

Note that the
$scope
is not injected into my controller and if I try using a custom filter I get the following error:


"Error: [filter:notarray]
errors.angularjs.org/1.5.8/filter/notarray?p0=0";


One last thing -- I'm told to avoid
includes
because of it not being supported widely enough (someone said something about
polyfill
being an alternative, but I'm not sure if it's applicable to this?).

Answer

You can use a custom filter attached to an object in your controller, as long as you put track by as the last statement in ng-repeat.

The filter in your controller would look like this:

menu.chickenFilter = function(item) {
  return (item.indexOf('chicken') > -1)
}

The ng-repeat would become:

<li ng-repeat="item in narrow.searchedMenu.description | filter: narrow.chickenFilter  track by $index">
         {{ narrow.searchedMenu.name[$index] }},
         {{ narrow.searchedMenu.short_name[$index] }},
         {{ narrow.searchedMenu.description[$index] }}</li>