AngularJs - Subproperty filtering as AND operation - angularjs

I've been trying to filter an array using Angular like this:
{{ (array | filter: { property: { subproperty: 'value' } }).length }}
and it works great.
Then I tried:
{{ (array | filter: { property: { subproperty1: 'value1', subproperty2: 'value2' } }).length }}
and noticed that Angular interprets this as an OR operation for the 2 subproperties.
How do I filter by 2 or more subproperties as an AND operation?
Thanks!

What you trying to do basically adding an additional filter to the current one. Try using the following and it should work as an AND filter.
{{ (array | filter: { property: { subproperty1: 'value1'}}
| filter: { property: { subproperty2: 'value2'}}).length }}
-- EDIT --
According to the angularjs docs:
A pattern object can be used to filter specific properties on objects contained
by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" AND property phone containing "1".
I prepared the following filter (arguments) based on the pointers in the docs and it works perfect for me.
{{ (array | filter: { property.subproperty1 : 'value1',
property.subproperty2 : 'value2' }).length }}
functional fiddle
P.S. - I also tried to figure out why your code was acting as an OR operator, but it never worked for me. non-functional fiddle
Cheers!

Related

Understanding the filter service from the API docs

The Angular API reference docs uses braces [] when defining the $filter service. What do the braces mean in this context?
{{ expression [| filter_name[:parameter_value] ... ] }}
I think it means optional. However, I've seen code written like this:
<select ng-model="query.level" class="input-medium">
<option selected value="">All</option>
<option selected value="introductory">Introductory</option>
<option selected value="intermediate">Intermediate</option>
<option selected value="advanced">Advanced</option>
</select>
<ul>
<li ng-repeat="session in event.sessions | orderBy:sortorder | limitTo:2 | filter:query">
...
</li>
</ul>
And a controller like
$scope.event = {
sessions: [
{
name: 'Blah',
level: 'Advanced'
},
{
name: 'another thing',
level: 'Intermediate'
}
]
}
query is not a custom or pre-built filter. I fail to see the connection between filter:query and the documentation. Is filter an expression that includes a magic variable somehow initialized simply by it's use in ng-model?
I think the confusion is that filter used in this context does not mean "Angular filter" it actually means filter the list. It's the "filter" filter. The part after the colon in this case is not the name of a filter, but the argument to the "filter" filter.
orderBy is a filter.
limitTo is a filter.
filter is also a filter.
You do not write filter:orderBy or filter:limitTo, you just write orderBy or limitTo. So in the this case, they are writing filter, not filter:filter.
To put it another way, query IS NOT A FILTER. query is the argument to the filter filter, which is included in the list of built-in filters: https://docs.angularjs.org/api/ng/filter
I think that was just bad naming on Angular's part.

How to pass value (true or false) for sorting tabular data in Angular JS ng-repeat

I want to determine the ascending/descending property of the ng-repeat by passing a value coming from a dropdown box.
I defined a variable called "asdc" whose value is determined by a dropdown box. This variable should determine if the table will be sorted ascending or descending. The variable already created in the AngularJS controller so I don`t post it here. I am pasting the codes below. It does not work this way. I am wondering what I am missing.
This is the table that I want to sort.
<tr ng-repeat="technology in technologies | limitTo: rowlimit | orderBy: sortby : adsc" >
<td>{{technology.name | uppercase}}</td>
</tr>
This is the drowdown box. It defines the value of adsc as true or false and passes the value to "adsc".
<select ng-model="adsc">
<option value="true">Asc</option>
<option value="false">Dsc</option>
</select>
Use ng-options to bind to something other than a string:
In controller:
$scope.directions = [
{
value: false,
label: 'Asc'
},
{
value: true,
label: 'Desc'
}
];
In view:
<select name="direction" ng-model="adsc"
ng-options="direction.value as direction.label for direction in directions">
</select>
Here's a plunkr demonstrating its use.
Also, note that passing true will sort in descending order, not ascending.

Use angularjs filter with parameters in the json

I want to filter a list and get all the elements which have an argument equals to true. But my argument is a property and I don't know how to tell to angularjs to compute it.
{{ list | filter: {argument: true} }}
For instance if I have scope.argument = 'foo' my html should interpret it like this
{{ list | filter: {'test': true} }}
Is it possible?
I found a solution.
I create a filter in my controller
scope.isSelected = function(element) {
return element[scope.argument] === true;
}
and then I use it in my html like this
{{ (list | filter: isSelected).length }}
I would prefer to do this directly in my html but I didn't find a way to do it.

How do I count object keys to determine an expression?

I'm trying to hide the parent element of a table (with rows created using ng-repeat) if the table is empty. I've found the follow example:
https://stackoverflow.com/a/14616397/930998
But that only applies to arrays. I have an object with nested objects like this:
{
"-J9dKgyHpCTNNImuydo6" : {
"url" : "http://www.example.se",
"title" : "Example 1",
"uuid" : "-J9dKgyHpCTNNImuydo6",
"sla" : false
},
"-J9dKQ2kxHzFc5-bJIKN" : {
"url" : "http://www.example.com",
"title" : "Example 2",
"uuid" : "-J9dKQ2kxHzFc5-bJIKN",
"sla" : true
}
}
My repeater looks like this:
<tr ng-repeat="site in sites | archived:false">
<td class="title">{{site.title}}</td>
<td class="url">{{site.url}}</td>
<td class="sla">{{site.sla | BooleanToText}}</td>
</tr>
As you can see I have a filter on the repeater as well. What I'm trying to do is hide the whole table if "site in sites | archived:false" is empty. I've tried the following:
ng-show="(sites | archived:false).length"
and
ng-show="(Object.keys(sites) | archived:false).length"
But I can't get it right. I think the length always returns 0 no matter what I do.
Here's a fiddle to make it more visible: http://jsfiddle.net/insats/djD4m/3/
I basically want to hide the wrapping div if the table is empty.
Maybe there is an easier solution but for sure this will work:
Add a method that indicates if the filtered collection is empty:
$scope.isNonArchivedSiteCollectionEmpty = function () {
... // you can use filter here or some simpler logic to determine if there is
... // at least one element in the collection
}
Then in your view just use:
ng-hide="isNonArchivedSiteCollectionEmpty()"
UPDATE Probably the most reasonable way is just to keep and refresh filter collection from the $scope and resign using filter in the markup altogether. Then you could very easily check if it is empty or not.

AngularJS: Filter ng-options not having specific values

I want to filter on a select like so :
<select ng-model="test" ng-options="c as c.label group by c.type for c in columns
| filter:{c.type:'!field'} | filter:{c.type:'!map'}"></select>
EDIT : Adding the column model :
Columns = [
{
name: "name",
label: "Label",
info: "Information displayed in help",
type: "type",
view: "html template",
style: "min-width: 10em;",
show: true
},
{
...
}
];
Columns is used for several things and to optimize my code I need it to be also in a Select, but without the entries whose type are 'field' nor 'map'
Yet, I get to choose from everything, even the entries which types are 'field' and 'map'.
Is there a clean way to do it ?
AngularJS NOT Filter
<select ng-model="test" ng-options="c as c.label group by c.type for c in columns
| filter:{ type : '!field' }
| filter:{ type : '!map' }">
</select>
Fiddle
From the docs:
"...The predicate can be negated by prefixing the string with !."
"A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1"..."

Resources