method called in ngFor gets trigger for multiple times

Viewed 2144

I am calling one method inside ngFor to get label of input its trigger for 8 times even in ngFor there is 2 item. It should be invoked for two times only. What could be the reason it is getting called for multiple times.

<form [formGroup]="parentForm">
   <div formGroupName="child">
    <ng-container *ngFor="let item of parentForm.get('child').controls | keyvalue; let i = index">
      <div class="form-group">
      <label>{{getLabel(item.key)}} {{i}} </label>
      <input type="text" [formControlName]="item.key">
      </div>
    </ng-container>
   </div>
  </form>   
  getLabel(item) {
     console.log('trigger item') // its get printed in console for 8 times
  if(item == 'data')  { 
    return 'Your Data' 
  } 
  return 'Your Name'
  }

Playground: https://stackblitz.com/edit/angular-ivy-hnaegv?file=src%2Fapp%2Fapp.component.html

2 Answers

As @ukn mentioned in the comment you should not use function calls on template.

getLabel function is executed every time Angular change detection runs.

You can to avoid multiple function calls, Using pipes. let Angular know that execution of a pipe can be skipped safely if the pipe’s input does not change

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'getLabel'
})
export class GetLabelPipe implements PipeTransform {

  transform(value: any, args?: any): any {
         console.log('trigger item')
  if(value == 'data')  { 
    return 'Your Data' 
  } 
  return 'Your Name'
  }

}

Example

its better to organize your data using javascript first. then your html should just display the data in the ngFor loop:

var displayItems = [];
parentForm.get('child').controls.forEach(item => {
    item.label = getLabel(item.key);
    displayItems.push(item);
});
this.displayItems = displayItems;

html;

<div *ngFor="let item of displayItems">
  <label>{{item.label}} {{i}} </label>
</div>
Related