In this tutorial, we’ll see how to use markForCheck() and detectChanges(), how they work, and the difference between them.
Angular provides several methods to update the view, including markForCheck() and detectChanges().
Choosing the appropriate method can have a significant impact on the performance of your application because these methods update the view in different ways.
Table of Contents
Prerequisites
To follow along with this tutorial, it would be helpful to have basic knowledge of Angular Change detection concept.
What is Change Detection?
Before diving into markForCheck() and detectChanges(), let’s first discuss quickly what change detection is in Angular.
Angular uses change detection to detect changes to the application state and update the view accordingly.
Change detection runs automatically when an event is triggered, such as a user clicking a button or data being fetched from an API.
Change detection can be triggered manually using the detectChanges() method provided by Angular.
However, manually triggering change detection too often can lead to performance issues, especially in large applications.
This is where markForCheck() comes in.
What is markForCheck() in angular ?
markForCheck() is a method provided by Angular that allows developers to mark a component for change detection.
When you call markForCheck() on a component, The component will be flagged and marked by Angular for a change detection check.
However, markForCheck() does not immediately trigger a change detection check, which can lead to better performance.
Let’s say we have a component that displays a user’s name and email address.
The user’s name is passed to the component as an input, and the email address is fetched from an API.
import { Component, Input, ChangeDetectorRef } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'user-details',
template: `
Name: {{ name }}
Email: {{ email }}
`
})
export class UserDetailsComponent {
@Input() name: string;
email: string;
constructor(private userService: UserService, private cdRef: ChangeDetectorRef) {}
ngOnInit() {
this.userService.getUserEmail(this.name)
.subscribe((email: string) => {
this.email = email;
this.cdRef.markForCheck();
});
}
}
In this example, we have a UserDetailsComponent
that has an @Input()
property called name
and a property called email
.
In the ngOnInit()
lifecycle hook, we fetch the user’s email address from an API using a UserService
.
Once we have the email address, we update the email
property and call markForCheck()
on the component’s cdRef
.
By calling
markForCheck()
instead ofdetectChanges()
, we are telling Angular that the component has been updated and needs to be checked for changes, but we don’t want to trigger a change detection check immediately.
This can lead to better performance, especially when dealing with large components or applications.
What is detectChanges() in angular ?
detectChanges() is a method provided by Angular that triggers a change detection check immediately.
When you call this method on a component. Angular will run a change detection cycle on the component and any child components.
This can be useful when you need to manually trigger change detection, such as when you’re using a third-party library that does not support Angular’s change detection.
Consider the case when we have a component that shows a list of items.
The products are fetched from an external API and displayed in a table. Every time a user clicks a button, we want to update and refresh the table.
import { Component, ChangeDetectorRef, OnInit } from '@angular/core';
import { ItemService } from './item.service';
@Component({
selector: 'item-list',
template: `
Name
Price
{{ item.name }}
{{ item.price }}
`
})
export class ItemListComponent implements OnInit {
items: any[];
constructor(private itemService: ItemService, private cdRef: ChangeDetectorRef) {}
ngOnInit() {
this.itemService.getItems()
.subscribe((items) => {
this.items = items;
});
}
refreshTable(): void {
this.itemService.getItems()
.subscribe((items) => {
this.items = items;
this.cdRef.detectChanges();
});
}
}
In this example, we have an ItemListComponent
that displays a list of items in a table.
The items are fetched from an API using an ItemService
and displayed using *ngFor
in the template.
We also have a button that triggers a refresh of the table data when clicked.
When the refreshTable()
method is called, we fetch the updated list of items from the API using the ItemService
.
Once we have the updated list, we update the items
property and call detectChanges()
on the component’s cdRef
.
By calling
detectChanges()
, we are telling Angular to immediately trigger a change detection check on the component and its child components.
This is necessary in this case because we want the table to update immediately when the user clicks the button.
The Difference Between markForCheck() and detectChanges()
The main difference between markForCheck()
and detectChanges()
is when they trigger change detection.
markForCheck()
marks a component for change detection, but does not immediately trigger a change detection check.
This can lead to better performance because Angular can batch change detection checks for multiple components together, reducing the number of times the application needs to run change detection.
detectChanges()
triggers a change detection check immediately.
This is useful when you need to manually trigger change detection, such as when using a third-party library that does not support Angular’s change detection.
Conclusion
In this tutorial, we explored what markForCheck()
and detectChanges()
are, how they work, and the difference between them.
markForCheck()
can improve performance by batching change detection checks, while detectChanges()
is useful for manually triggering change detection.
Choosing the right method for your application can have a significant impact on performance, so it’s important to understand the differences between the two.