How to use the Ion Searchbar with Databases


#1

I’ve been making an app to display and search acronyms. The displaying Acronyms bit is working great but because the database I have put in is pre-populated, I can’t seem to find anyone who knows how to put in search. It was suggested that I use the Ion Search bar and told it could be done by adding this–

Create a new function with queryAcronyms name like below and filter your data according search query and reinitialize your array
public queryAcronyms(){
    let temparray  =  [];
    temparray =  this.acronyms.filter((item) => {
        return item.name.toLowerCase().indexOf(this.queryText.toLowerCase()) > -1;
    });
    this.acronyms = temparray;
}

But I have so far been unable to successfully implement this into my app and the person I was talking to is now unreachable. Does anyone know how I’d be able to do this or have another way to implement search. I simply need it to be searchable by the acronym name.

Home.html–

<ion-content padding>
	<ion-searchbar (ionInput)="queryAcronyms($event)"></ion-searchbar>
	<ion-list>
		<ion-item text-wrap *ngFor="let name of acronyms; let nIndex = index">
		<h2>{{ name.name }}</h2>
		<p>{{ name.meaning }}</p>
	</ion-item>
	</ion-list>
</ion-content>

Home.ts–

export class HomePage {
  public storage: SQLite;
  private options = { name: "data7.db", location: 'default', createFromLocation: 1 };
  public queryAcronyms = "SELECT * FROM acronymsFinal";

  public acronyms: any = [];

  constructor(public navCtrl: NavController) {
    this.storage = new SQLite();
    this.storage.openDatabase(this.options).then((success) => {
      this.storage.executeSql(this.queryAcronyms, {}).then((data) => {
        let rows = data.rows;
        for (let i = 0; i < rows.length; i++) {
			this.acronyms.push({
				name: rows.item(i).name,
				meaning: rows.item(i).meaning
			});
		}
      });
    });
  }
}


#2

Try giving this a shot

<ion-content padding>
	<ion-searchbar [(ngModel)]="mySearch"></ion-searchbar>
	<ion-list>
		<ion-item text-wrap *ngFor="let name of acronyms; let nIndex = index">
			<div *ngIf="matchesSearch(name)">
				<h2>{{ name.name }}</h2>
				<p>{{ name.meaning }}</p>
			</div>
		</ion-item>
	</ion-list>
</ion-content>

export class HomePage {
	private mySearch = "";

	matchesSearch(acronym) {
		if(this.mySearch.trim()) { // checks null and ""
			if(/* Some compare logic (== or .test or whatever)*/) {
				return true;
			} else {
				return false;
			}
		} else { // Nothing in search input
			return true;
		}
	}
}

I have only included my changes in the HomePage class, so you of course still need the code which is currently there. The reason the *ngIf is not in the ion-item, is because of the *ngFor. Sometimes they got some issues with one another, you can try putting the if in there after the for, and remove the div if you want. No guarantee that will work, though :stuck_out_tongue:


#3

Are you sure the platform is ready by the time you start trying to interact with SQLite?


#4

Sorry, you’ll have to clarify what you mean by that. It’s correctly calling and displaying the database in the app, albeit it is a little bit slow in appearing. Up to now, I have yet to get a successful build after adding in the new Search code but I am still trying.


#5

What errors are you getting when building?

If it’s being slow when initially displaying the list, it’s most likely because there’s a lot to display at once. Pagination would be a good idea :slight_smile:


#6

Constructors get called very early. You may wish to inject Platform and wrap your calls to SQLite in a platform.ready().then clause.


#7

Hi thanks for all your help and sorry for the late reply. I put the project on hold as I was getting a little bit tired of the lack of progress… As I said before, I’ve only been doing Ionic for a short amount of time and so I don’t particularly understand the code you have provided. I understand most of the logic behind it but if you were able to provide the ‘compare logic’ you described above, I’m sure that would at least get us a little closer to the goal. Been reading through the compare logic on the Search bar documentation but cannot see how to fit this into your provided code. I would really like to get this working as I think it would be excellent help for anyone else using Pre-Populated DB’s on Ionic 2, for which I have found extremely little in the way of documentation overall. But we’ve got this far so I’m hoping to make it all the way!

PS-For now I’m just hoping to get the code working so speed will come after that.


#8

If you want to keep it simple you could just do if(acronym.name.indexOf(this.mySearch.trim())>-1 || if(acronym.meaning.indexOf(this.mySearch.trim())>-1) {...}, a more advanced solution would be to split the search by e.g. spaces and check each word with acronym.name/meaning and give it a score. Then sort by the score or only show the ones above X. I don’t know what’s ideal in this situation, though, or if the examples I provided are ideal at all.