1

I have a component that displays dynamic, read-only data. For example:

<div>{{getText()}}</div>

I noticed that getText is being invoked over and over by Angular, even if there is seemingly no need to do so, i.e. no data has changed. How can I detect when Angular triggers view refresh?

1
  • without OnPush Change detection, Angular need "check" is the variables of the interpolation in the .html has changed. When you use a function in template Angular should evaluate to know if has changed (when you have a variable only "check" the "actua"l value and the "old" value). This is the reason to try avoid use functions in HTML to interpolate -unless the function was very very simple, e.g. a getter Commented Nov 28, 2024 at 7:22

2 Answers 2

2

You can detect it using the ngDoCheck hook. Which fires during a change detection cycle.

On each cycle the function gets called and the function is evaluated.

If you want to improve performance, you can enable ChangeDetectionStrategy.OnPush, which will reduce the number of change detection cycles.

Angular OnPush Change Detection and Component Design - Avoid Common Pitfalls


The more easier solution is to evaluate the function and store it in a property which you show in HTML, then you can rerun the function to update the property whenever it will change.

export class SomeComponent { @Input() conditionToUpdateText: string; displayProp = '';

ngOnInit() {
  this.getText();
}

getText() {
  this.displayProp = this.conditionToUpdateText === 'hello' ? 'world' : 'asdf';
}

ngOnChanges() {
    this.getText();
}

In the above example we set the initial value of displayProp on the ngOnInit hook (during initialization), then since the data is dependent on the inputs, we use the ngOnChanges hook ( when inputs change ) to reevaluate the property. The HTML usage will be:

{{displayProp}}

Although it is ok for simple functions to fire multiple times during change detection, as a rule of thumb avoid functions since if you accidentally use a costly array operation like find in the HTML binding, it gets called multiple times and causes a drop in performance.

Sign up to request clarification or add additional context in comments.

Comments

1

This is expected - on every change detection cycle all expressions in the template are re-evaluated. There is one other approach which is not mentioned in the other answer. You can use Signals instead, which allow fine-grained reactivity and avoids unnecessary computations.

To give an example:

export class MyComponent {
  name = input<string>();
  text = computed(() => `Hello ${this.name()}!`);
}

This example uses the new signal-based input() function and computes a text based on the input value, using a computed function. Here, the computation for the text is only performed if one of the signals inside the computed function changed their value, which avoids unnecessary computations.

Finally, you can display the text in the template like the following:

<div>{{ text() }}</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.