vjnan369
vjnan369

Reputation: 853

UI values are not updating in ngFor based on ion search

My html code

  <ion-searchbar (ionInput)="getFilteredItems($event)"></ion-searchbar>

    <button ion-item *ngFor="let patient of surveyPatients" (click)="showPatientData(patient)">{{patient.name}} - {{patient.age}} - {{patient.idCardNumber}}</button>

Corresponding ts code

surveyPatients:any;

getFilteredItems(ev: any) {    
    this.initializeSurveyPatients();
    let val = ev.target.value;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatients = this.surveyPatients.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
       console.log(this.surveyPatients.length); 
    }
  }


initializeSurveyPatients() {


        this.afoDatabase.list('/SurveyPatients',
      {
        query:{
              orderByChild: 'district',
              equalTo: 'Nalgonda '
            }
      }

      ).subscribe(snap => {

      this.surveyPatients = snap;
    });


  }

When I see value of console.log(this.surveyPatients.length); In getFilteredItems() method I am getting expected values before and after filter, Which confirms us that filter is working fine.

But after the filter operation the list in the UI is not updating accordingly.

I am not sure what I am missing to add.

Please help me in resolving this issue.

Upvotes: 1

Views: 437

Answers (1)

Gabriel Barreto
Gabriel Barreto

Reputation: 6421

I think that the case is that your filter is called before the Firebase can get the list items, and when he gets it reinitialize the filtered array. You need to do something like this:

surveyPatients:any;

getFilteredItems(ev: any) {
  let val = ev.target.value;
  this.initializeSurveyPatients().subscribe(snap => {
    this.surveyPatients = snap;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatients = this.surveyPatients.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
      console.log(this.surveyPatients.length); 
    }
  });
}


initializeSurveyPatients() {
  return this.afoDatabase.list('/SurveyPatients', {
    query:{
          orderByChild: 'district',
          equalTo: 'Nalgonda '
        }
  });
}

This way you'll wait for the database query to be over so you can filter your itens.

And if you're using an event on your html input so everytime a user inputs a letter it filters, then your firebase method can be called several times and reloads your patients list more times.

And just another thing, i've never used AngularFire2 myself, but subscribing to a list doesn't mean that you'll have an observable in that node of your database? This is bad because your object can be reseted without further warning and this is REALLY BAD UX.

You should have 2 patients variables, one to receive the database results everytime it updates and another to be used in your filter:

surveyPatients:any; // to be observed
surveyPatientsFiltered: any; // to be used in filter

ionViewWillLoad(){ // WHEN LOADING OR ENTERING PAGE YOU'LL SUBSCRIBE TO THE EVENT AND SAVE THE RESULTS IN YOUR VAR
  this.afoDatabase.list('/SurveyPatients',
  {
    query:{
          orderByChild: 'district',
          equalTo: 'Nalgonda '
        }
  }).subscribe(snap => {
    this.surveyPatients = snap;
  });
}

getFilteredItems(ev: any) {    
    this.initializeSurveyPatients();
    let val = ev.target.value;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatientsFiltered = this.surveyPatientsFiltered.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
       console.log(this.surveyPatients.length); 
    }
  }

initializeSurveyPatients(){
  this.surveyPatientsFiltered = this.surveyPatients;
}

With this your filter will be faster since you don't have to wait for firebase to end a query, there's no concurrence problems and your surveyPatients will always be updated without the user needing to update it manually when it filter.

Hope this helps.

Upvotes: 2

Related Questions