Ionic searcher with json array

I have taken the search bar demo docs and changed the code to use this.items as a json array and not strings. I keep getting an EXCEPTION: Error during evaluation of “input”. yet if I go back to string there are no problems. i am just experimenting at this time to see what can be done with Ionic 2 search. Here is a sample of the code

html

<ion-navbar *navbar>
   <ion-title>Searchbar</ion-title>
</ion-navbar>

<ion-content padding class="status">

     <ion-searchbar [(ngModel)]="searchQuery" (input)="getItems($event)"></ion-searchbar>

  <ion-list>
      <ion-item *ngFor="#item of items">
           {{ item.name }}<br>{{ item.position}}
      </ion-item>
  </ion-list>
</ion-content>

js

import {Page} from 'ionic/ionic';

@Page({
templateUrl: 'build/pages/status/status.html',
})
export class Status {
   constructor() {
        this.searchQuery = '';
        this.initializeItems();
}

initializeItems() {
  this.items = [
      {"name":"Moby Dick","position":"Big ass whale"},
      {"name":"Jaws","position":"Fish with anger issues"}
  ];
}

getItems(searchbar) {
  // Reset items back to all of the items
  this.initializeItems();
  // set q to the value of the searchbar
  var q = searchbar.value;
  // if the value is an empty string don't filter the items
  if (q.trim() == '') {
    return;
  }

   this.items = this.items.filter((v) => {

    if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
       return true;
      }

      return false;
    })

 }
}

When you do the filter, it exposes the v as an object of array.

v.toLowerCase() will not work as objects aren’t string.

You need to specify what you’re searching for.

Change:

v.toLowerCase()

to

v.name.toLowerCase()

This will look to see if your input matches any names in your array.

1 Like

Ok maybe not that obvious the way i said it, yours more explicit :stuck_out_tongue:

Thanks, that really helped as I was reading up on pipes as filters etc… It is people like yourself and luchillo17 that help out the rest of us new guys.

did that work for you? Because for me the indexof throws error.

Edit:
ok for some reason now it doesn’t throws an error (I think it was the changes I did to the tconfigjson or maybe is VSCode being crappy) but it doesn’t give me do anything to the array. It does inside the method but after the method does its thing I check the array again (from a button with a method with an alert) and it says the array is the same as originally.

Edit:
Got it to work. The html was fine (it is a little different from the example as I used the one they taught at angular.io) but the code is a little bit different.

What I did was the array initializer I put it inside the
if(q.trim()== ’ '){
initializeArray();
return;
}

The thing is that everytime I made changes it was initializing the array all the time. So what I did was I only initialized when the ion-searchbar is empty/whitespace/null (call it whatever.)

1 Like

You Edit actually helped. Once I began importing my Array from Sqlite db I was getting the same error. Now it works again.

If getting values from database, take in account the async nature of the query.

I know http.get would be async. but I am using

initializeItems() {
    this.storage.get("corptest").then((value) => {
    this.items = ("value", JSON.parse(value));
    })
}

What would I have to do different in my filter. In http.get I would require a

this.items = null;

in the constructor( )

Nop, actually you should set it to an empty array, after all it is a collection that Angular 2 will try to iterate over:

In constructor:
  this.items = []

By the way what is this supposed to do? i can’t wrap my head around this code:

('value', JSON.parse(value))

What it does it takes to value from the KV pair


and parses it as a json

That’s the JSON.parse() part, what does the ('value', json)? while testing why is it the same as just JSON.parse() alone:

('value', JSON.parse(value)) == JSON.parse(value)

Hi, do you have the full code you used for importing the array ?

I save the data to sqlite with a http provider and used the following to use the key value pair in a contacts page

import {Page, NavController, Storage, SqlStorage} from 'ionic-angular';

@Page({
  templateUrl: 'build/pages/contactMain/corp-contacts/corp-contacts.html',
})
export class CorpContacts {
    nav;
    corp;
    storage;
    searchQuery;
    corpResults;

    constructor(nav: NavController) {
        this.nav = nav;
        this.storage = new Storage(SqlStorage, {name: 'app_data'});
        this.getCorpContacts
        this.corp = [];
        this.searchQuery = '';
        this.getCorpContacts();
    }

    getCorpContacts() {
        this.storage.get("corpContact").then((value) => {
        this.corpResults = JSON.parse(value);
        this.corp = this.corpResults;
        })
    }

    getCorp() {
        this.corp = this.corpResults;
    }

    getItems(searchbar) {
        this.getCorp();

        var q = searchbar.value;

        if (q.trim() == '') {
            return;
        }

        this.corp = this.corp.filter((v) => {

            if (v.name.toLowerCase().indexOf(q.toLowerCase()) > -1) {
                return true;
            }

            return false;
        })
    }

    onCancelSearchbar(searchbar) {
        this.getCorp();
    }

    onClearSearchbar(searchbar) {
        this.getCorp();
    }
}

html

<ion-navbar *navbar calm>
<ion-title>Corp Contacts</ion-title>
</ion-navbar>

<ion-content padding class="corp-contacts">
    <ion-searchbar [(ngModel)]="searchQuery" (input)="getItems($event)" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)"></ion-searchbar>
    <br>
    <ion-list>
        <ion-card *ngFor="#item of corp">
            <ion-card-header>
                <b>{{ item.name}}</b><br>{{ item.position}}
            </ion-card-header>

            <ion-card-content>
                <a href="tel:{{item.cell}}"><button large outline><ion-icon name="ios-phone-portrait"></ion-icon></button></a>

                <a href="tel:{{item.phone}}"><button large outline><ion-icon name="ios-call"></ion-icon></button></a>

                <a href="sms:{{item.sms}}"><button large outline><ion-icon name="ios-chatbubbles"></ion-icon></button></a>

                <a href="mailto:{{item.email}}"><button large outline><ion-icon name="ios-mail"></ion-icon></button></a>
            </ion-card-content>
        </ion-card>
    </ion-list>
</ion-content>
1 Like

I am able to do it.

<ion-searchbar (ionInput)=“getItems($event)” [(ngModel)]=“test”>

  • {{emp.firstName}}

Here your searchBar and the list of items iterated through *ngFor.

You have to make some changes in the logic part.

getUsers() {
this.http.get(this.url).subscribe(res => {
** this.employees = res.json();**
** });**
}

ngOnInit() {
this.getUsers()
}

initialize(){
this.items = this.employees;
}

getItems(ev: any) {
// Reset items back to all of the items
//if(ev.target.value === “”){
this.initialize();
//}
// 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) => {
let name: any = item;
return (name.firstName.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}

This highlighted part is the modification I made. Hope this will help you

hey thomas, where I had to put a json file?

You should put it inside the folder src/assets/data/data.json and you declare it like this:

  this.http.get('assets/data/data.json').subscribe(res => {

help me :cry:

What to do if i want to search with name or position

hai i am now working in search filter.I am using json filter in search filter.But in that i am having one problem in that.in my page i getting all value.But when i type anything in search bar means it occur error.can you pls help me

HOME.ts

import { Component } from ‘@angular/core’;
import { NavController } from ‘ionic-angular’;
import {PeopleServiceProvider} from ‘…/…/providers/people-service/people-service’;
@Component({
selector: ‘page-home’,
templateUrl: ‘home.html’,
providers: [PeopleServiceProvider]
})
export class HomePage {
data;
public users: any;

constructor(public navCtrl: NavController,public peopleService: PeopleServiceProvider) {
this.loadPeople();

}

loadPeople()
{
  this.peopleService.load()
    .then(data => {
      this.users = data;

      console.log(this.users);

    });

}

getItems(ev) {
// Reset items back to all of the items
this.loadPeople();

// set val to the value of the ev target
var val = ev.target.value;

// if the value is an empty string don't filter the items
if (val && val.trim() != '') {
  this.users = this.users.filter((item) => {
    return (item.toUpperCase().indexOf(val.toUpperCase()) > -1);
  })
}

}

}

HOME.html

Ionic Blank {{user.advertiserName}} ![image](upload://qdOGajK0ydonOlXR4BukSDehTFn.png)