I have been working on this for over a week and am finally at the edge of my sanity and could really use some help
The code below works great in pulling in data via http.get and displaying in my app with nearly zero delay and scrolling with virtualScroll works great in keeping things fast. But, I get the runtime error item.toLowerCase is not a function
.
data.ts
import { Injectable } from "@angular/core";
import { Http } from "@angular/http";
import "rxjs/add/operator/map";
@Injectable()
export class Data {
items: any;
constructor(public http: Http) {}
load() {
if (this.items) {
// already loaded data
return Promise.resolve(this.items);
}
// don't have the data yet
return new Promise(resolve => {
this.http
.get("https://www.soledadmemorial.com/api/v1/plaques")
.map(res => res.json())
.subscribe(data => {
this.items = data;
resolve(this.items);
});
});
}
}
home.ts
import { Component } from "@angular/core";
import { IonicPage, NavController, LoadingController } from "ionic-angular";
import { Http } from "@angular/http";
import { Data } from "../../providers/data/data";
@IonicPage()
@Component({
selector: "page-home",
templateUrl: "home.html",
providers: [Data]
})
export class HomePage {
searchQuery: string = '';
items: string[];
constructor(
public navCtrl: NavController,
public http: Http,
public dataService: Data,
public loadingCtrl: LoadingController
) {
this.loadData();
}
loadData() {
this.presentLoadingDefault();
this.dataService.load().then(data => {
this.items = data
});
}
getItems(ev: any) {
// Reset items back to all of the items
this.loadData();
// 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);
})
}
}
...
}
home.html
...
<ion-content>
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
<ion-list [virtualScroll]="items">
<ion-item *virtualItem="let item" (click)="goToFeed(item)">
<ion-thumbnail item-start>
<img src="https://www.soledadmemorial.com/{{item.image_url}}">
</ion-thumbnail>
<h2>{{item.veteran_first}} {{item.veteran_last}}</h2>
<p>{{item.veteran_rank}} {{item.veteran_branch}}</p>
<button ion-button clear item-end><ion-icon name="arrow-dropright"></ion-icon> </button>
</ion-item>
</ion-list>
</ion-content>
To test the filter, I adjusted my home.ts
file to the code below and it works as it should. "Notice the hard-code items list, changed the init of items from a string to items = []
and added the veteran_first
into the filter code. So I am thinking I need to call the loadData from my data.ts file something like item.veteran_first ..
But, my skill level is not there to figure that out.
Here is the test home.ts code.
import { Component } from "@angular/core";
import { IonicPage, NavController, LoadingController } from "ionic-angular";
import { Http } from "@angular/http";
import { Data } from "../../providers/data/data";
@IonicPage()
@Component({
selector: "page-home",
templateUrl: "home.html",
providers: [Data]
})
export class HomePage {
searchQuery: string = '';
items = [];
constructor(
public navCtrl: NavController,
public http: Http,
public dataService: Data,
public loadingCtrl: LoadingController
) {
this.loadData();
}
loadData() {
this.items = [
{veteran_first: 'one'},
{veteran_first: 'two'},
{veteran_first: 'three'},
{veteran_first: 'four'},
{veteran_first: 'five'},
{veteran_first: 'six'}
]
}
getItems(ev: any) {
// Reset items back to all of the items
this.loadData();
// 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.veteran_first.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
...
}
Thank you for your help!!