I'm very new to Typescript and Ionic 2 and I'm trying to filter trough a json response with Ionic 2 search bar.
This is my code:
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
posts: any;
private searchQuery: string = '';
private items: string[];
constructor(private http: Http) {
this.initializeItems();
this.http.get('https://domain.co/open.jsonp').map(res => res.json()).subscribe(data => {
this.posts = data;
console.log(this.posts);
});
}
initializeItems() {
this.items = this.posts;
}
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.items = this.items.filter((item) => {
return (item.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
}
And the Markup:
<ion-header>
<ion-searchbar (ionInput)="getItems($event)" [debounce]="500" placeholder="Suchen..."></ion-searchbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let post of posts">
<h1>{{post.storeName}}</h1>
</ion-item>
</ion-list>
</ion-content>
I this error when I search:
item.toLowerCase is not a function
The JSON data looks like this:
[
{
storeName: "Avec Hauptbahnhof",
addressLink: "",
phone: "0326223902",
image: "",
description: "",
link: "",
openingHours: [
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"06.30 - 22:00",
"7.00 - 22.00"
]
},
{
storeName: "Manor",
addressLink: "",
phone: "0326258699",
image: "",
customer: "",
description: "",
link: "",
openingHours: [
"09.00 - 18.30",
"09.00 - 18.30",
"09.00 - 18.30",
"09.00 - 21:00",
"09.00 - 18.30",
"08.00 - 17.00",
"Geschlossen"
]
}
]
You're getting that error because each item is not a string, but an object, so instead of doing
item.toLowerCase().indexOf(val.toLowerCase()) > -1
You should do
item.storeName.toLowerCase().indexOf(val.toLowerCase()) > -1
Also please notice that in your view you're using the posts array
*ngFor="let post of posts"
But you should use the items array instead, because that's the one that is going to be filtered
<ion-list>
<ion-item *ngFor="let item of items">
<h1>{{item.storeName}}</h1>
</ion-item>
</ion-list>
Besides that, I'd do things a little bit different, just to make sure that the user is able to use the page only when the data is available (since you're using an http request to obtain it). In order to do so, I'd add a loading alert and would remove it as soon as the http request is done. As of Ionic2-beta.11, you could do that like this:
import { Component } from '@angular/core';
import { NavController, LoadingController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
private posts: any; // <- I've added the private keyword
private searchQuery: string = '';
private items: any; // <- items property is now of the same type as posts
constructor(private http: Http, private loadingCtrl: LoadingController) {
// this.initializeItems(); <- you don't need this anymore
// Show the loading message
let loadingPopup = this.loadingCtrl.create({
content: 'Loading posts...'
});
this.http.get('https://domain.co/open.jsonp').map(res => res.json()).subscribe(data => {
this.posts = data;
this.initializeItems();
// Hide the loading message
loadingPopup.dismiss();
});
}
initializeItems() {
this.items = this.posts;
}
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.items = this.items.filter((item) => {
return (item.storeName.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With