Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array.filter() in Angular 2 Component

In one component I can filter my array using the following:

// Array of product objects
const result = products.filter(p => p.name.includes('val'));

and value of products remains same as the first value but filtered value stores in result.

But in the following code, filter() filters array of strings itself:

// Array of strings
const result = strs.filter(s => s.includes('val'));

The question is how can I filter strings and return result without modifying the strs itself?

Note: I tried with array.filter(function() { return res; }); but didn't make any change.

like image 872
Hooman Avatar asked Nov 11 '17 08:11

Hooman


2 Answers

It returns the filtered ones and don't change the actual array. You are doing something wrong

const strs = ['valval', 'bal', 'gal', 'dalval'];
const result = strs.filter(s => s.includes('val'));

console.log(strs);
console.log(result);
like image 101
Suren Srapyan Avatar answered Nov 07 '22 00:11

Suren Srapyan


First thing we need to know is, if we filter our list we loose our original data

products: any[] = [
 {
  "productId": 1,
  "productName": "foo-bar",
  "price": 32.99
 }
]

and can't get it back without re-getting the data from it's source so we have to make another list to store the filtered list.

 filteredProduce: any[];

Next if you are working to show a list of filtered product on a grid or something like this we need a way to know when the user changes the filter criteria. we could use event binding and watch for key presses or value changes, but an easier way is to change our _listFilter property into a getter and setter, like this

get listFilter: string {
    return this._listFilter;
}
set listFilter(value:string) {
    this._listFilter= value;
}

next we want to set our filteredProducts array to the filtered list of products like this

set listFilter(value:string) {
    this._listFilter= value;
    this.filteredProducts = this._listFilter? this.performFilter(this._listFilter) : this.products;
}

in preceding code we are using js conditional operator to handle the posibility that _listFilterstring is empty, null or undefined. Next we use this.performFilter(this._listFilter) to filter our list.

performFilter(filterBy: string): any[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: any) =>
        product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

Finally we should assign the main list of products to the filteredProducts and _listFilter to what we want.

constructor() {
        this.filteredProducts = this.products;
        this._listFilter= 'foo-bar';
    }

last step is to change our template to bind to our filteredProducts property.

like image 39
Mohammad Hashemi Avatar answered Nov 06 '22 23:11

Mohammad Hashemi