Reputation: 996
Scratching my head over this...
I have a function called filterProducts that is called in my Angular 2 component anytime a user clicks a checkbox. For now, the method finds all checkboxes that are checked with a specific class name, gets their values, and then attempts to sort an array. Fairly simple...
// Called when any checkbox is checked or unchecked
filterProducts() {
// Grab all "Program" checkboxes that are checked
var programsToInclude = $(".programCheckbox:checkbox:checked").map(function () { return this.value; });
// If any "Program" checkboxes are checked, filter the list accordingly
if (programsToInclude)
this.filteredProducts = this.filteredProducts.filter(x => programsToInclude.indexOf(x.programName) > -1);
}
Why am I getting the following error?
ORIGINAL EXCEPTION: TypeError: programsToInclude.indexOf is not a function
programsToInclude is definitely a string array, which should have this function, no?
Upvotes: 1
Views: 3936
Reputation: 1074385
programsToInclude
isn't an array, it's a jQuery object. jQuery objects have a lot of array methods, but not all.
To get an array after using jQuery#map
, you need to tack a .get()
on the end:
var programsToInclude = $(".programCheckbox:checkbox:checked").map(function () { return this.value; }).get();
// ---------------------------------------------------------------------------------------------------^^^^
if (programsToInclude) { // <== This check is pointless, see below the fold for why
this.filteredProducts = this.filteredProducts.filter(x => a.indexOf(x.programName) > -1);
}
Alternately, use get
early to get a native array, which requires adjusting your filter
call:
var programsToInclude = $(".programCheckbox:checkbox:checked").get().map(function(e) { return e.value; });
// -----------------------------------------------------------------^^^^----------^-----------^
if (programsToInclude) { // <== Again, see below the fold
this.filteredProducts = this.filteredProducts.filter(x => programsToInclude.indexOf(x.programName) > -1);
}
In both cases, though, programsToInclude
ends up being an array. If you want to use it as a jQuery object again later, you have to convert it back. If you do want to use it later, you might have the array separate:
var programsToInclude = $(".programCheckbox:checkbox:checked").map(function(e) { return e.value; });
if (programsToInclude) { // <== Same note
let a = this.programsToInclude.get();
this.filteredProducts = this.filteredProducts.filter(x => a.indexOf(x.programName) > -1);
}
Why the check is pointless: A jQuery object, even an empty one, is always truthy. If you want to check for an empty one, use if (obj.length)
. But there's not much point in such a check if you're about to do filter
, filter
is a no-op when the object is empty anyway.
Upvotes: 3