Search code examples
angularionic-frameworkionic4

ionChange event firing twice with dynamic ion-segment


Here's the console log

Console log

It's firing once with the static ion-change segment, but twice with dynamic, here's my code so you can understand it better.

<ion-segment *ngIf='!isLoading' scrollable="true" value="all" (ionChange)="segmentChanged($event)" style="place-content: center;">
  <ion-segment-button value="all">
    <ion-label>All</ion-label>
  </ion-segment-button>
  <ion-segment-button [value]="c.payload.doc.data().name" *ngFor="let c of categorys">
    <ion-label>{{ c.payload.doc.data().name }}</ion-label>
  </ion-segment-button>
</ion-segment>

segment change code

 segmentChanged(ev: any) {
    if (ev.detail.value === 'all') {
      this.feedSub = this.feedService.getAll().subscribe(results => {
        this.allposts = results.sort((a, b) => a.dateCreated <= b.dateCreated ? 1 : -1);
        console.log(ev.detail.value);
      });
    }else {
      this.feedSub = this.feedService.getAll().subscribe(results => {
        this.allposts = results.sort((a, b) => a.dateCreated <= b.dateCreated ? 1 : -1);
      });
      this.allposts = this.allposts.filter((post) => {
        console.log(ev.detail.value);
         // console.log(post.category.name.match(ev.detail.value));
        return post.category.name.match(ev.detail.value);
      });
    }
  }

Solution

  • You code is probably working as expected, i.e., the ionChange is firing only once.

    The several messages you see in console are caused by this console.log inside the filter function:

    this.allposts = this.allposts.filter((post) => {
      console.log(ev.detail.value);
      return post.category.name.match(ev.detail.value);
    });
    

    When you call filter and supply a function, that function will be executed once for each post in allposts. Thats why the message is being outputed in the console n times, being n the total number of posts.

    What you may change in your code:

    1 - Place the console.log(ev.detail.value); on top of the segmentChange function (and not inside the filter).

    2 - It is not related to you question, but it is recommended to call the filter only after the subscription is fired and the this.allposts value is setted:

    this.feedSub = this.feedService.getAll().subscribe(results => {
        this.allposts = results.sort((a, b) => a.dateCreated <= b.dateCreated ? 1 : -1);
    
        this.allposts = this.allposts.filter((post) => {
          return post.category.name.match(ev.detail.value);
        });
    });