Why ng-if function repeating itself?

Viewed 386

I am passing a boolean function in ngIf attribute instead of boolean condition in html template file. But that boolean function is repeating itself based on amount of data in variable messages. If messages have 2 objects than value of ctr in console is increasing from 1 to 69 approx instead of just 1 or 2. What could be the reason for it and how to avoid it while passing function in ngIf attribute?

HTML

<ion-row *ngFor="let message of messages; let i = index; trackBy:trackByMsgId">
      <ion-badge *ngIf="isNewDate(i)" color="primary" class="ion-margin">{{message.time | date: 'longDate'}}</ion-badge>
</ion-row>

TS

let ctr = 0;
isNewDate(i) {
    this.ctr += 1;
    console.log('ctr: ', this.ctr);
    return true;
}
1 Answers

The isNewDate() function will be called every time the Angular runs ChangeDetection based on the ChangeDetectionStrategy, Because Angular cannot predict whether the return value of isNewDate() function has changed. So, it needs to execute the function every time change detection runs.

Updating DOM is a part of ChangeDetection and ngFor directive updated the DOM, and will run the Angular ChangeDetection. So if you have an array with length 4 and ChangeDetection runs 4 times 4 each item, your function will be called 16 times, but component variable ctr will be restarted per each item. You can see a sample here on Stackblitz. So, thanks for @Adam helpful comment and according to the mentioned article:

While function calls in Angular templates are super convenient and technically valid, they may cause serious performance issues.

And because of that you should never use function calls in Angular template expressions. It's not a best practice.

The solution to avoid function calls:

  1. Use pipes
  2. Manually calculate the values and update some Variables in app.component.ts and using them in template (app.component.html).
Related