Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does filter work in AngularJS?

I have a table generated with ng-repeat (from an objects' array).

I would like to filter it with a search text field.

Objects contained in my array has got deep properties.

I don't know why and how, but the filter is only working on email field, which is as deep as other properties.

I'm using this search form :

<input type="text" name="search" ng-model="searchText" />
...
<tr ng-repeat="x in obj | filter:searchText track by $index">
  ...
</tr>

plunker

EDIT :

This answer helps me to understand why it's not working. Someone knows how I can bypass the $ verification in filter ?

I'm using $ because I'm following the Google Contact API format.

like image 748
Zooly Avatar asked May 02 '17 10:05

Zooly


People also ask

What does filter function do in angular?

AngularJS filter Filter The filter filter allows us to filter an array, and return an array containing only the matching items. This filter can only be used for arrays.

What is the correct way to apply filter in AngularJS?

In AngularJS, you can also inject the $filter service within the controller and can use it with the following syntax for filter. Syntax: $filter("filter")(array, expression, compare, propertyKey) function myCtrl($scope, $filter) { $scope. finalResult = $filter("filter")( $scope.

What are filters in AngularJS explain built in filters with suitable examples?

Filters can be added in AngularJS to format data to display on UI without changing the original format. Filters can be added to an expression or directives using the pipe | symbol. AngularJS Filters: AngularJS provides filters to transform data of different data types.


3 Answers

You can check the source code of ngFilter here It is set to ignore keys starting with $ as it's a prefix used by AngularJS for public ($) and private ($$) properties.

like image 187
John Avatar answered Dec 05 '22 22:12

John


$ is a prefix used by Angular internal properties. For technical reasons, Angular prevents you to use it. Here is a workaround to deal with $ properties names without changing your JSON object:

You can iterate in ng-repeat over Object.keys($scope.object) instead $scope.object.

Demo on JSFiddle

like image 35
Mistalis Avatar answered Dec 05 '22 23:12

Mistalis


Since it is clear that we can change neither third party API nor AngularJS library code, we could go for modifying the object keys to not have $ in the beginning. But, since the data has so many of them at multiple level, let's do it recursively! :)

Here's how. I would remap each object in $scope.obj array to call a function:

$scope.obj = $scope.obj.map(function(cur) {
  return renameKey(cur)
})

Now, inside renameKey, it would check whether it's an Array or Object using helper functions and call itself recursively while replacing the keys prepending x for the strings starting with $

function renameKey(cur) {
  if(isArray(cur)) {
    cur.forEach(function(obj) {
      obj = renameKey(obj)
    })
  } else if (isObject(cur)) {
    for (let key in cur) {
      if(key.charAt(0) === '$') {
        cur['x'+key] = cur[key];
        delete cur[key];
      }
      cur[key] = renameKey(cur[key])
    }
  } 
  return cur
}

function isObject(obj) {
   return obj && (typeof obj === "object");
}

function isArray(obj) { 
  return isObject(obj) && (obj instanceof Array);
}

Looks little tedius but it does work! Now, all we need to do is have x$t instead of $t in the HTML, and boom!

working plunker

like image 39
tanmay Avatar answered Dec 05 '22 22:12

tanmay