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.
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.
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.
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.
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.
$
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
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With