Reputation: 7138
I have search-bar that I want to filter my array results but it does not return results.
HTML
// search bar
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
// results
<ion-list *ngIf="showList" class="studentsList">
<ion-item *ngFor="let student of students">
{{student.name}}
</ion-item>
</ion-list>
Component
students: any[] = []; // sample data array provided below
showList: boolean = false;
searchQuery: string = '';
getItems(event) {
if (event != '') {
this.students = this.students.filter((v) => {
return (v.name.toLowerCase().indexOf(event.srcElement.value.toLowerCase()) > -1);
});
this.showList = true;
} else {
this.showList = false;
}
console.log('count: ', event.srcElement.value, this.students.length);
}
Sample data array
{
"data": [
{
"id": 4,
"name": "Arina",
"username": "arina",
"email": "[email protected]",
},
{
"id": 5,
"name": "Tom",
"username": "tom",
"email": "[email protected]",
}
],
"message": "Students are ready."
}
Any idea?
requested data screenshot
Upvotes: 3
Views: 963
Reputation: 31873
There are a couple of issues in your method
getItems(event) {
if (event != '') {
this.students = this.students.filter((v) => {
return (v.name.toLowerCase().indexOf(event.srcElement.value.toLowerCase()) > -1);
});
this.showList = true;
} else {
this.showList = false;
}
console.log('count: ', event.srcElement.value, this.students.length);
}
Firstly, event
is not a string based on what you have passed from your Angular markup, $event
, so if (event != '')
will always be true
.
So we actually want to compare the value of the event, with ''
to make sure there is text entered.
We can solve both issues with a minor refactoring as follows
getItems(event: Event) {
const value = event.target.value;
if (value !== '') {
this.students = this.students.filter((v) => {
return (v.name.toLowerCase().indexOf(value.toLowerCase()) > -1);
});
this.showList = true;
} else {
this.showList = false;
}
console.log('count: ', value, this.students.length);
}
As Micheal D astutely observes, if we assign the filtered students
to students
property, we will lose the ability to reset any filtering because we won't have the original array.
To resolve this, we need to store the original students in a dedicated property so we can reset our filtered collection back to it. In fact, we should do this when the filter value is emtpty
// original students array.
students: Student[] = [];
// filtered array we iterate over in search results
matchingStudents = [];
getItems(event: Event) {
const value = event.target.value;
if (value !== '') {
this.matchingStudents = this.students.filter((v) => {
return (v.name.toLowerCase().indexOf(value.toLowerCase()) > -1);
});
this.showList = true;
} else {
this.showList = false;
}
console.log('count: ', value, this.matchingStudents.length);
}
Finally, I'll do some additional cleanup since your filter can be simplified making it simultaneously more readable and concise
getItems(event: Event) {
const value = (event.target.value || '').toLowerCase();
this.showList = value !== '';
if (showList) {
this.matchingStudents = this.students.filter(v => v.name.toLowerCase().includes(value));
}
console.log('count: ', value, this.students.length);
}
Template
// search bar
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
// results
<ion-list *ngIf="showList" class="studentsList">
<ion-item *ngFor="let student of matchingStudents">
{{student.name}}
</ion-item>
</ion-list>
Upvotes: 3
Reputation: 31125
I see multiple issues.
You're assigning the filtered students back to the this.students
variable. So for the next search, the source list isn't available anymore. I'd say you could introduce another variable to hold the filtered students list.
You're checking for an empty event field with condition event != ''
whereas it should actually be event.srcElement.value != ''
.
Try the following
Controller
studentsFiltered = [];
getItems(event) {
if (event.srcElement.value != '') {
this.studentsFiltered = this.students.filter((v) => {
return (v.name.toLowerCase().indexOf(event.srcElement.value.toLowerCase()) > -1);
});
this.showList = true;
} else {
this.showList = false;
this.studentsFiltered = [];
}
console.log('count: ', event.srcElement.value, this.studentsFiltered.length);
}
Template
<ion-list *ngIf="showList" class="studentsList">
<ion-item *ngFor="let student of studentsFiltered">
{{student.name}}
</ion-item>
</ion-list>
Upvotes: 3