I am trying to filter an array (list) of repeated objects, based on the value of one of the property. However I keep getting [filter: not array] error. Screenshot of the error:
angular error message
I have also tried adding this angular toArrayFIlter injector https://github.com/petebacondarwin/angular-toArrayFilter however, the error still pops out.
Any help is much appreciated!
My array:
var orders = [
{
"assignedBy": "system",
"serviceDate":"2017-11-13",
"serviceStartTime":"04:00 PM"
},
{
"assignedBy": "system",
"serviceDate":"2017-11-13",
"serviceStartTime":"07:00 AM"
}];
html
<ul ng-repeat="task in orders track by $index | filter: { serviceStartTime: '04:00 PM' }">
<li >
<p>{{task.serviceDate}}</p>
<p>{{task.serviceStartTime}}</p>
</li>
</ul>
You'll need to filter the array before iterating it, like this:
<ul ng-repeat="task in (orders | filter: { serviceStartTime: '04:00 PM' }) track by $index ">
I'm getting two items back from my API, one has a startDate and one has an endDate and I was wondering if it's possible to order them by their parameter string?
Data:
[
{
name: "Item 1",
type: "Start Time"
},
{
name: "Item 2",
type: "End Time"
}
]
Something like so:
<li ng-repeat="item in items | orderBy: type='Start Time'">{{ item.name }}</li>
Is is possible using Angular's orderBy filter?
Any help is appreciated.
No need to specify StartTime,
<li ng-repeat="item in items | orderBy: 'type'>{{ item.name }}</li>
Here is the working Application
You only need to specify the key by which you want to order in your orderBy:
orderBy: 'type'
And if you want to reverse the order use -:
orderBy: '-type'
I'm currently using a text input to filter a list of items. I'd like to make it so when a particular variable is set, the list doesn't filter, regardless of what the text input is. Any advice on how I can accomplish this?
<a ng-repeat="set in data | filter: { value: search }" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>
You can achieve this if you set the filter expression to '' (or undefined) - this causes the filter not to be applied - for when your disableFilter is set, or to the actual filter expression otherwise.
EDIT 2:
The other answer (below by #Ryan) is simpler and easier to understand. Can't remember now whether it didn't work for me initially or I simply didn't think of this simpler way.
So, assuming, this toggling variable - disableFilter - is a boolean :
<a ng-repeat="set in data | filter: (!disableFilter || '') && filterExpression">
(with filterExpression being whatever the expression you want to filter by). Your specific case would be:
<a ng-repeat="set in data | filter: (!disableFilter || '') && {value: search}">
EDIT:
To explain how the above works.
Remember that || and && return the value of one of its operands.
|| and && use short-circuit evaluation - true || (anything) returns true; false && (anything) returns false - without evaluating the (anything) expression.
'' is falsy (or use undefined instead, if it's clearer)
And so,
when disableFilter === true, !disableFilter === false, thus the second operand of || - the empty string '' - is evaluated (it's falsy), and (!disableFilter || '') returns '' - a falsy value, which short-circuits the && operation and does not evaluate the second operand of &&. The return value of the expression is thus ''.
when disableFilter === false, !disableFilter === true, which short-circuits the || operation, then the second operand of && is evaluated and returned. The return value of the expression is thus {value: search}.
Read more about logical operators here
I think the following is a slightly less tricky solution. Tricky solutions cause bugs for future developers.
Here's my suggestion:
<a ng-repeat="set in data | filter: (shouldFilter ? filterExpression : '')">
or
<a ng-repeat="set in data | filter: (shouldFilter ? {value: search} : '')">
Simply, if shouldFilter, then give it your filter expression, otherwise give it nothing.
Using a simple ternary expression will be easier for readability.
Maybe use an ng-if?
<a ng-if="!myConditional" ng-repeat="set in data" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>
<a ng-if="myConditional" ng-repeat="set in data | filter: { value: search }" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>
That seems to be the solution.
Here is what I did. First, I had a select control, populated from my controller, with one static item (Select...) with a zero length string value:
<select data-ng-model="districtFilter" class="form-control" data-ng-options="d.DistrictId as d.DistrictName for d in districts | orderBy: 'DistrictName'"><option value="">Select...</option></select>
Then I applied the filter conditionally on the table. It appears when the filter is null, setting it to undefined clears it:
<tr data-ng-repeat="courtEntity in courts | filter:{ 'DistrictId' : districtFilter === null ? undefined : districtFilter}">
I had a complicated case
Have a list of records say it products
Filter by two other property prop1, prop2 selected by user from drop down
Another dropdown (prop3) have two value 1 and 2, if user select 2 filter should not be applied
Hers is my outcome:
ng-repeat="prod in filterdProd =
(products | filter : model.prop3 == 2 ? '' :
{ 'prop1': model.prop1 || 'none',
'prop2': model.prop2 }) |
orderBy: 'productrName'"
if model.prop3 == 2 ? '' filter will not apply otherwise ...
We can also use the count of records by using filterdProd
I found the following solution more easy and effective
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.package=[{"PkgServiceId":null,"PkgServicesName":" HB, TLC, DLC & ESR, EDTA WHOLE BLOOD, HBSAG CONFIRMATION,SERUM, Blood Cholesterol","PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":108,"ServiceName":"Family Health Package"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":70,"ServiceName":"HB, TLC, DLC & ESR, EDTA WHOLE BLOOD"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":71,"ServiceName":"HBSAG CONFIRMATION,SERUM"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":3,"ServiceDesc":"Its used to evaluate your overall health and detect a wide range of disorders","ServiceId":2,"ServiceName":"Blood Cholesterol"},{"PkgServiceId":null,"PkgServicesName":" MRI Test, HB, TLC & DLC, EDTA WHOLE BLOOD","PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":107,"ServiceName":"Child Health Package"},{"PkgServiceId":107,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":"Its used to evaluate your overall health and detect a wide range of disorders","ServiceId":5,"ServiceName":"MRI Test"},{"PkgServiceId":107,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":69,"ServiceName":"HB, TLC & DLC, EDTA WHOLE BLOOD"}] ;
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in package">
{{ x.ServiceName }}
</li>
</ul>
<p>Above is the total data set without filtering.</p>
<ul>
<li ng-repeat="x in package| filter :{PkgServiceId: null}">
{{ x.ServiceName }}
{{ x.PkgServiceId }}
</li>
</ul>
</div>
<p>This example displays only the packages containing the packageId "null".</p>
</body>
</html>
In HTML Template Binding
{{ dataX | date: expression ? 'dd/MM' : 'dd/MM/yyyy' }}
Make functions and combine with filterExpression.
Example I have a students list as below:
$scope.students = [
{ name: 'Hai', age: 25, gender: 'boy' },
{ name: 'Hai', age: 30, gender: 'girl' },
{ name: 'Ho', age: 25, gender: 'boy' },
{ name: 'Hoan', age: 40, gender: 'girl' },
{ name: 'Hieu', age: 25, gender: 'boy' }
];
I want to filter students via gender to be boy and filter by name of them.
The first I create a function named "filterbyboy" as following:
$scope.filterbyboy = function (genderstr) {
if ((typeof $scope.search === 'undefined')||($scope.search === ''))
return (genderstr = "")
else
return (genderstr = "boy");
};
Explaination: if not filter name then display all students else filter by input name and gender as 'boy'
Here is a demo How to use and operator in AngularJs example
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.
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!