简体   繁体   中英

indexOf is not a function - Angular 2 / Typescript

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM