0
votes

I am calling a function from inside an angular template (interpolation), strangely the function is getting invoked four times !!

I do know how change detection works in angular, as I understood change-detection process kickstarts if binding value gets updated.

In this scenario, I am not binding / changing any thing as such..

var i = 0;

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>{{ parentCounter() }}</h1>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    
  }
  
  parentCounter(){
    alert(`${++i} called`);
    return 5;
  }
}

Ref: https://plnkr.co/edit/pta0s0nzcsLdTsjCtb3D?p=preview

Note: Template got compiled four times before the async event

Template got compiled four times before the async event

2

2 Answers

1
votes

If you bind to functions in the view like

<h1>{{ parentCounter() }}</h1>

then Angular calls this function every time change detection is run.

If this function returns a new object every time it is called, you'll even get an exception in development mode.

Expression has changed since it was last checked

It is better to assign the result of the call to a field and bind to that field instead.

var i = 0;

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>{{ counter }}</h1>
    </div>
  `,
})
export class App {
  name:string;
  counter:number;
  constructor() {
    this.counter = this.parentCounter();
  }

  parentCounter(){
    alert(`${++i} called`);
    return 5;
  }
}
1
votes

enter image description here

enter image description here

As stated in the previous answer comments there are two calls each time as you can see in the pictures to check that the value hasn't changed due to subsequent calls (idempotent test). The first set of 2 calls is initiated from the bootstrap/initial parsing of the page, the second pair of calls is triggered as the result of the readystatechange event firing off and the automatic zone/async handler triggering a view update.


Also just to add this is really going to be insignificant. Performance issues arise from pages that have components typically in repeaters with tons of data bindings leading to pages with 10s of thousands of data bindings (and then people complain that it is slow :) ) Check out the timeline and chrome profiling tools they are invaluable, also to dig into this myself I used a debugger keyword and the call stack to see what was going on in general.