I am using the Array.prototype.filter() method to filter an array into 2 sets of elements and then iterating through those 2 sets with Knockout, though I believe the issue is JS related. I would like to take the truthy elements and make set A and the falsy and make set B. So, for falsy I attempt to negate the function, but the following error occurs. I could create a second method to perform the negation, however I'm interested in this solution. Thanks.
Array.prototype.filter: argument is not a Function object
HTML:
<!-- ko foreach: Items.filter(IsSetA) -->
<h1>Is Set A</h1>
<!-- /ko -->
<!-- ko foreach: Items.filter(!IsSetA) -->
<h1>Is Set B</h1>
<!-- /ko -->
JS:
function IsSetA(item) {
return item.category === 'A';
}
I am using the Array.prototype.filter() method to filter an array into 2 sets of elements and then iterating through those 2 sets with Knockout, though I believe the issue is JS related. I would like to take the truthy elements and make set A and the falsy and make set B. So, for falsy I attempt to negate the function, but the following error occurs. I could create a second method to perform the negation, however I'm interested in this solution. Thanks.
Array.prototype.filter: argument is not a Function object
HTML:
<!-- ko foreach: Items.filter(IsSetA) -->
<h1>Is Set A</h1>
<!-- /ko -->
<!-- ko foreach: Items.filter(!IsSetA) -->
<h1>Is Set B</h1>
<!-- /ko -->
JS:
function IsSetA(item) {
return item.category === 'A';
}
Share
Improve this question
asked Jul 3, 2017 at 14:20
GilliganGilligan
5011 gold badge5 silver badges14 bronze badges
2
-
3
You need to negate the return value, not the predicate function itself:
Items.filter(v => !IsSetA(v))
– Bergi Commented Jul 3, 2017 at 14:24 - @Bergi - I do like this approach, but unfortunately browser support will not allow currently. Thank you. – Gilligan Commented Jul 3, 2017 at 15:29
2 Answers
Reset to default 6Array.prototype.filter()
requires you to pass a function that it will execute on each item. IsSetA
by itself works because it's a function, but negating that with the !
operator casts it to a boolean value, which simply isn't something accepted by filter
.
Alternatively, you could either create helper functions and use them in your template:
function IsSetATruthy(item) {
return IsSetA(item);
}
function IsSetAFalsy(item) {
return !IsSetA(item);
}
or write the same as inline functions:
<!-- ko foreach: Items.filter(function(item) { return IsSetA(item); }) -->
<h1>Is Set A</h1>
<!-- /ko -->
<!-- ko foreach: Items.filter(function(item) { return !IsSetA(item); }) -->
<h1>Is Set B</h1>
<!-- /ko -->
or use arrow functions if your target supports them:
<!-- ko foreach: Items.filter(item => IsSetA(item)) -->
<h1>Is Set A</h1>
<!-- /ko -->
<!-- ko foreach: Items.filter(item => !IsSetA(item)) -->
<h1>Is Set B</h1>
<!-- /ko -->
You're trying to negate a function reference. What you were trying to do is negate the result of the function. The positive case works (filter expects a function reference), but the negative will not, so negate the result manually:
<!-- ko foreach: Items.filter(IsSetA) -->
<h1>Is Set A</h1>
<!-- /ko -->
<!-- ko foreach: Items.filter(function(val){ return !IsSetA(val); }) -->
<h1>Is Set B</h1>
<!-- /ko -->