I have a question how to use ionic searchbar to filter items in a nested JSON object. As I've tried to filter the header
item it worked perfectly fine but it does not work for the name
wrap inside the brands
.
{
"items": [{
"header": "A",
"brands": [{ "name": "Apple", "id": "1" }, { "name": "Adidas", "id": "2" }]
},
{
"header": "B",
"brands": [{ "name": "Bose", "id": "3" }, { "name": "Boss", "id": "4" }, { "name": "Birkenstock", "id": "5" }]
},
{
"header": "M",
"brands": [{ "name": "McDonalds", "id": "6" }]
}
]
}
My search.ts
:
private result: any[];
private searchItems: any;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private http: Http
) {
let localData = this.http.get('assets/search-brand.json').map(res => res.json().items);
localData.subscribe(data => {
this.result = data;
});
this.initializeItems();
}
initializeItems() {
this.searchItems = this.result;
}
getItems(ev: any) {
// Reset items back to all of the items
this.initializeItems();
// set val to the value of the searchbar
let val = ev.target.value;
// if the value is an empty string don't filter the items
if (val && val.trim() != '') {
this.searchItems = this.searchItems.filter((item) => {
return (item.header.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
My code (search.html
):
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
<p>{{test}}</p>
<ion-list *ngFor="let item of searchItems; let i = index">
<ion-list-header>
{{item.header}}
</ion-list-header>
<ion-item *ngFor="let brands of item.brands; let j = index" (click)="selectedBrand(brands.id)">{{brands.name}}</ion-item>
</ion-list>
This one is working for filtering the brands.name
it said .toLowerCase() is not a function
.
Your JSON data maybe have some element with header == null
or does not have brands
propertive. So to ensure the search work properly, you should handle these case by if
statement. You need to rewrite filter function to get expected output.
Try this:
this.searchItems = this.searchItems.map((item)=>{
if(item && item.brands && item.brands.length > 0){
item.brands = item.brands.filter(brand=>{
if(!brand.name) return false;
return brand.name.toLowerCase().indexOf(val.toLowerCase()) > -1;
});
}
retrun item;
})