1

I am generating a list to search for the key "name" and "type".

results.push({ name: item.beast, type: 'color of animal' });

but I see this error to find an element that is contained in the array $scope.data:

Error: [$ rootScope: infdig] $ 10 digest () iterations reached. Aborting! Watchers fired in the last five iterations.

This is the code that I have:

http://plnkr.co/edit/EDd578?p=preview

  • it is basically mean: you somehow triggered a potential infinity loop and angular detected scope's cycle keep getting updated for some reason. (Looking into your code now, hope I can find a better answer for you ) – Linh Pham Dec 31 '15 at 04:46
  • i dont know what do.. –  Dec 31 '15 at 05:21
  • Yes, me neither. I understand why you are getting the issue. It is because a new array got to be created everytime you loop throught an item.... Hope I can find a work-around for it :D – Linh Pham Dec 31 '15 at 07:37
  • After many tries in approach of using filter and creating a new array structure like you did. There is no way to make it work with a filter (interesting idea tho). The idea is too much outside of the box, which is unsupported by angular. For general idea, I will suggest you did as answer of @jusopi, as filter follow the principle "It mean to filter out (remove) unmatching items in an array, but not customize the array to something that is not like original one". – Linh Pham Dec 31 '15 at 08:37
  • P.S. I could give more explaination about "**why it does not work with angular**", but it is related with **$digest** and **$scope life cycle** and stuff. Which is very complicated for new beginner. So just take the principle I mention above and avoid to forces filter to do something outside of the box. – Linh Pham Dec 31 '15 at 08:41

2 Answers2

1

The problem here is that you're using a set of data to filter against but trying to display a resulting data set from that filtering process that's in a different format. I'd advocate using ng-change on the input and using a new data set to fill the repeated items.

controller

$scope.matches = [];

$scope.findMatches = function(items, searchText) {
var results = [];
if (searchText) {
  angular.forEach(items, function(item) {
    if (item.beast.indexOf(searchText) === 0) {
      results.push({
        name: item.beast,
        type: 'animal'
      });
    }

    if (item.color.indexOf(searchText) === 0) {
      results.push({
        name: item.color,
        type: 'color of animal'
      });
    }
  });
}

return results;
}

html

<input type='text' ng-model='search' id='search' ng-change="matches = findMatches(data, search)">
<hr/>

<ul>
  <li ng-repeat="item in matches track by $index">{{item.name}} and {{item.type}}</li>
</ul>

plunkr - http://plnkr.co/edit/hkMXPP?p=preview

jusopi
  • 6,791
  • 2
  • 33
  • 44
  • thanks but we have lost the essence of what I had. if you look, I need to return the "beast" and "color" property. I need to return an object with only those 2 properties. if I write "r" must appear: rat ,red –  Dec 31 '15 at 05:14
  • ergo the statement "You'll need to modify your template to fix the missing props since now it's processing actual items rather than new matched items." – jusopi Dec 31 '15 at 05:17
  • if I write "r" should list all the properties in both "beast" com "color". in my example would rat and red. how it works in my example I uploaded –  Dec 31 '15 at 05:19
  • Obviously the end goal is to find matching items. That's nothing new, but the way you're displaying that content is not your standard approach. If you were open to maybe using the existing items for your match and maybe displaying it differently, you might have an easier time finding a solution. As it stands now, I'm stuck with the same $digest error you have regardless of my approach when using the matches-creation setup. – jusopi Dec 31 '15 at 05:39
  • haha I'm in trouble. I tried many things but I get the solution –  Dec 31 '15 at 05:41
  • I finally got it working, I had a typo that was failing silently. Check out the updated plunkr and answer. – jusopi Dec 31 '15 at 05:49
  • when I re-forked it, I had copied and pasted `$query` where it was expecting `searchText`. Because it was in the binding, it failed without error. BTW, if this works for you, please considering selecting this as the appropriate answer. Thanks. – jusopi Jan 01 '16 at 04:03
0

You are creating a new array everytime your filter is run, and returning that. This makes angular think you've changed the array everytime (it doesn't check for item equality, rather, reference equality by ===).

Have a look at this for more details.

A solution is to modify the items array inplace, and return it, so the reference remains the same.

Community
  • 1
  • 1
UtsavShah
  • 857
  • 1
  • 9
  • 20