How Angular detects changes

Nikita Poltoratsky
Nikita Poltoratsky

GDE for Angular and Web Technologies

May 11, 2018

How Angular detects changes

Hey Guys!

Every developer wants to build fast and robust Angular applications. But to be able to, you need to dive into the Angular internal structure and obtain comprehensive understanding how it works and sometimes it is not that easy from the first try.

In this article, I'll try to give you a superficial idea of how Angular works under the hood not going in too much of detail.

The main concept of the Angular internals that we need to discuss is Change Detection - process that checks if data has been changed and re-renders components’ templates.

Let's break it into the following topics:

  • The internal representation of Angular applications
  • (Who triggers change detection)
  • What change detection does
  • How Angular updates DOM
  • Why we need ExpressionChangedAfterItHasBeenCheckedError

Internal representation

When you build an Angular application you start from AppComponent, then you create more and more components, combine them in modules and use these components here and there. Thus, we can imagine Angular application as a tree of components, but it only scratches the surface. Let's figure out what the Angular application actually consists of.

If you create a simple component like this:

and build your application in aot mode, you'll be able to find component factory generated by the Angular compiler. It will look like a simplified factory:

Component factory describes the structure of the component view and is used when instantiating ViewDefinition.

ViewDefinition is like a template which is used when instantiating components. For each component, Angular instantiates ViewData that contains component instance, its state, children, parent and bounded properties.

As we can see now, the Angular application is not just a tree of components but a tree of ViewData instances and our components are just fields of that view data instances. Moreover, Angular runs change detection process over ViewData, not over components itself.

Who triggers change detection?

Ok, now we know how angular represents our applications and what instances are used to perform change detection’s tasks.

Before digging into change detection process I want to tell you what actions and events are responsible for triggering this process:

  • Developer through ChangeDetectorRef
  • Output events of the components
  • Async browser APIs (XHR, setTimeout, click, etc.) with help of Zone.js.

More details you can find by the links above but let's focus on Zone.js now.

Zone.js

I don't want to be too specific about Zone but in few words, you can think about it as a tool that provides you with a capability to hook into your code execution process and track when a part of your code has started or finished execution. For example in the case below we use afterTask hook that will be run when a code in the run method finished its execution, including asynchronous tasks. So this hook will be executed only when setTimeout is completed:

And that’s a point. Zone is an execution context that persists across async tasks. Angular has Zone wrapper called NgZone that gives a capability to do something similar to the code below, meaning, subscribe to events fired by zone and run change detection loop:

Can I run something outside change detection?

Angular subscribes to the most of the browser events and runs change detection as a reaction but if you want to run some process that doesn't require DOM updates you can run it outside change detection within runOutsideAngular method of the NgZone. This may be useful for sending analytics to the server from time to time because we don't need to update application UI during this process.

Change detection flow

It's time to investigate what change detection exactly does. If it’s been triggered it starts from the root component, checks it and proceeds to the children. As you can see in the picture below change detection can be triggered on any component and always starts from the application root.

Change detection flow

During the change detection on a component angular does the following steps:

  • Update input properties for child components
  • Call ngOnChanges, ngOnInit and ngDoCheck hooks on all child components
  • Update DOM for the current component
  • Run change detection for all child components
  • Call ngAfterViewInit lifecycle hook for all child components

Let's imagine that we have three components:

Change Detection flow for these components will be the following:

  • Checking A component:
  • update B input bindings
  • call ngOnChanges, ngOnInit and ngDoCheck on the B component
  • update DOM for component A
  • Checking B component:
  • update C input bindings
  • call ngOnChanges, ngOnInit and ngDoCheck on the C component
  • update DOM for component B
  • Checking C component:
  • update DOM for component C

OnPush Strategy

As we can see, calling ngOnChanges and ngDoCheck hooks doesn't mean component has been checked. These hooks are called when change detection process is focused on the component parent, so ngDoCheck of the B component will be called when change detection is checking A component.
This may lead your application to the strange behavior when you're using OnPush strategy.

I mean, if we make changeDetectionStrategy of B component OnPush and don't change input props B component will not be checked but ngDoCheck hook will be triggered.

  • Checking A component:
  • update B input bindings
  • call ngDoCheck on the B component
  • update DOM interpolations for component A
  • if (bindings changed) -> Checking B component

OnPush Strategy Emulation

For a better understanding how OnPush strategy works, let's see how we can emulate it. Using ChangeDetectorRef of the component we can detach it when instantiating and stop detecting changes on it. Anyway, as we know from examples above ngOnChanges hook will be called on this component even though it's detached because it'll be called when change detection checks its parent.

ngOnChanges will be called only if property binding has been changed. Sounds similar to the OnPush strategy, right? So, if input bindings have changed we have to reattach component and allow change detection process it. And then detach it again asynchronously.

DOM updates

I think it's time to discuss the most important step of change detection - updating DOM representation of the checked component.

Do you remember this simple component from the first part of the article?

Let's look closer to another part of the component factory that wasn't mentioned previously:

The purpose of this function is to check and update component DOM representation if bindings are changed.

Update renderer function receives checkAndUpdate function and ViewData instance that contains current component. It calls checkAndUpdate for each binding in the component template. If you have multiple bindings in template like these:

Update renderer will perform multiple calls of the checkAndUpdate:

checkAndUpdate function is just a router that chooses specific checkAndUpdate* function depends on binding type:

I think the simplest checkAndUpdate function is checkAndUpdateText and its code looks like the snippet below. It just checks that rendered values and new ones that aren't the same and then updates component DOM:

This means that each property of component template will be checked and updated separately, and if you changed only one text node of the component only this text node will be re-rendered, not all the template. This behavior helps angular reach high-speed rendering.

Why we need ExpressionChangedAfterItHasBeenChecked Error?

Angular has another important underlying concept that helps us to keep view and model of an application consistent. Let's look at this example:

According to the change detection steps for this example:

  • Update DOM for the current component
  • Call ngAfterViewInit lifecycle hook for all child components

ngAfterViewInit of the ChildComponent will be called after updating the DOM of the ParentComponent. However, ngAfterViewInit changes parents name property which rendered in the parent template. Do you see that? Something goes wrong... Change detection has rerendered ParentComponent and then its child changes its name property.

And after that, we have inconsistency - rendered name property of the ParentComponent isn't equal actual name property because it has been changed after rendering.

Great, we’ve defined the problem, so has Angular. This is the reason why angular runs second change detection loop in the development mode for verification purpose. This verification loop checks that actual properties in components equal rendered and bounded properties and if they do not, then angular throws ExpressionChangedAfterItHasBeenCheckedError.

Let's check another example which reveals property binding issue:

We have a quite similar example to the previous one but with two differences:

1) ParentComponent passes input property for its ChildComponent
2) ChildComponent changes ParentComponent.text property in its ngOnInit hook

This code leads us to the similar error as mentioned above, but why?

It changes input bindings between parent and itself. As you remember from Change Detection Flow part, the order of change detection operations is the following for this example:

  • Update input properties for child components
  • Call ngOnChanges, ngOnInit and ngDoCheck hooks on all child components

But in the snippet, we change parent input binding in ngOnInit hook - after binding has been updated. Verification loop checks this inconsistency and throws the exception.

If you have this error it means you're doing something wrong with updating component properties when it had already been rendered or bounded.

To avoid such error, you have to remember about change detection operations order and update your data in the right lifecycle hooks.

Hopefully, you've found this topic useful. Keep reading our blog and see you on our meet-ups!

Contact us
Akveo's case

Billing Automation for a SaaS Company with Low-Code

Our client needed a robust billing solution to manage hierarchical licenses, ensure compliance, and automate invoicing for streamlined operations.

The solution:
We developed a Retool-based application that supports multi-tiered licenses, automates invoicing workflows, and integrates seamlessly with CRM and accounting platforms to enhance financial data management.

The result:

  • Achieved 100% adherence to licensing agreements, mitigating penalties.
  • Automated invoicing and workflows reduced manual effort significantly.
  • Dashboards and reports improved decision-making and operational visibility.

Learn more about the case

See More
See Less
Akveo's case

Retool Dashboards with HubSpot Integration

Our client needed a centralized tool to aggregate account and contact activity, improving visibility and decision-making for the sales team.

The solution
We built a Retool application integrated with HubSpot, QuickMail, and Clay.com. The app features dashboards for sorting, filtering, and detailed views of companies, contacts, and deals, along with real-time notifications and bidirectional data syncing.

The result

  • MVP in 50 hours: Delivered a functional application in just 50 hours.
  • Smarter decisions: Enabled data-driven insights for strategic planning.
  • Streamlined operations: Reduced manual tasks with automation and real-time updates.

Learn more about the case

See More
See Less
Akveo's case

Lead Generation Tool to Reduce Manual Work

Our client, Afore Capital, a venture capital firm focused on pre-seed investments, aimed to automate their lead generation processes but struggled with existing out-of-the-box solutions. To tackle this challenge, they sought assistance from our team of Akveo Retool experts.‍

The scope of work
The client needed a tailored solution to log and track inbound deals effectively. They required an application that could facilitate the addition, viewing, and editing of company and founder information, ensuring data integrity and preventing duplicates. Additionally, Afore Capital aimed to integrate external tools like PhantomBuster and LinkedIn to streamline data collection.

The result
By developing a custom Retool application, we streamlined the lead generation process, significantly reducing manual data entry. The application enabled employees to manage inbound deals efficiently while automated workflows for email parsing, notifications, and dynamic reporting enhanced operational efficiency. This allowed Afore Capital's team to focus more on building relationships with potential founders rather than on administrative tasks.

Learn more about the case

See More
See Less
Akveo's case

Retool CMS Application for EdTech Startup

Our client, CutTime, a leading fine arts education management platform, needed a scalable CMS application to improve vendor product management and user experience.

The scope of work
We developed a Retool application that allows vendors to easily upload and manage product listings, handle inventory, and set shipping options. The challenge was to integrate the app with the client’s system, enabling smooth authentication and product management for program directors.

The result
Our solution streamlined product management, reducing manual work for vendors, and significantly improving operational efficiency.

Learn more about the case

See More
See Less
Akveo's case

Building Reconciliation Tool for e-commerce company

Our client was in need of streamlining and simplifying its monthly accounting reconciliation process – preferably automatically. But with a lack of time and low budget for a custom build, development of a comprehensive software wasn’t in the picture. After going through the case and customer’s needs, we decided to implement Retool. And that was the right choice.

The scope of work

Our team developed a custom reconciliation tool designed specifically for the needs of high-volume transaction environments. It automated the processes and provided a comprehensive dashboard for monitoring discrepancies and anomalies in real-time.

The implementation of Retool significantly reduced manual effort, as well as fostered a more efficient and time-saving reconciliation process.

→ Learn more about the case

See More
See Less
Akveo's case

Creating Retool Mobile App for a Wine Seller

A leading spirits and wine seller in Europe required the development of an internal mobile app for private client managers and administrators. The project was supposed to be done in 1,5 months. Considering urgency and the scope of work, our developers decided to use Retool for swift and effective development.

The scope of work

Our developers built a mobile application tailored to the needs of the company's sales force: with a comprehensive overview of client interactions, facilitated order processing, and enabled access to sales history and performance metrics. It was user-friendly, with real-time updates, seamlessly integrated with existing customer databases. 

The result? Increase in productivity of the sales team and improved decision-making process. But most importantly, positive feedback from the customers themselves.

→ Learn more about the case

See More
See Less
Akveo's case

Developing PoC with Low Code for a Tour Operator

To efficiently gather, centralize, and manage data is a challenge for any tour operator. Our client was not an exception. The company was seeking to get an internal software that will source information from third-party APIs and automate the travel itinerary creation process. Preferably, cost- and user-friendly tool.

The scope of work

Our experts ensured the client that all the requirements could be covered by Retool. And just in 40 hours a new software was launched. The tool had a flexible and easy-to-use interface with user authentication and an access management system panel – all the company needed. At the end, Retool was considered the main tool to replace the existing system.

→ Learn more about the case

See More
See Less
Akveo's case

Testing New Generation of Lead Management Tool with Retool

Our client, a venture fund, had challenges with managing lead generation and client acquisition. As the company grew, it aimed to attract more clients and scale faster, as well as automate the processes to save time, improve efficiency and minimize human error. The idea was to craft an internal lead generation tool that will cover all the needs. We’ve agreed that Retool will be a perfect tool for this.

The scope of work

The project initially began as a proof of concept, but soon enough, with each new feature delivered, the company experienced increased engagement and value. 

We developed a web tool that integrates seamlessly with Phantombuster for data extraction and LinkedIn for social outreach. Now, the company has a platform that elevates the efficiency of their lead generation activities and provides deep insights into potential client bases.

→ Learn more about the case

See More
See Less
Akveo's case

Building an Advanced Admin Portal for Streamlined Operations

Confronted with the need for more sophisticated internal tools, an owner of IP Licensing marketplace turned to Retool to utilize its administrative functions. The primary goal was to construct an advanced admin portal that could support complex, multi-layered processes efficiently.

The scope of work

Our client needed help with updating filters and tables for its internal platform. In just 30 hours we've been able to update and create about 6 pages. Following features were introduced: add complex filtering and search, delete records, styling application with custom CSS. 

Together, we have increased performance on most heavy pages and fixed circular dependency issues.

→ Learn more about the case

See More
See Less
Akveo's case

Creating MVP Dashboard for Google Cloud Users

Facing the challenge of unoptimized cloud resource management, a technology firm working with Google Cloud users was looking for a solution to make its operations more efficient. The main idea of the project was to create an MVP for e-commerce shops to test some client hypotheses. Traditional cloud management tools fell short.

The scope of work

Determined to break through limitations, our team of developers turned Retool. We decided to craft an MVP Dashboard specifically for Google Cloud users. This wasn't just about bringing data into view; but about reshaping how teams interact with their cloud environment.

We designed a dashboard that turned complex cloud data into a clear, strategic asset  thanks to comprehensive analytics, tailored metrics, and an intuitive interface, that Retool provides. As the results, an increase in operational efficiency, significant improvement in cost management and resource optimization.

→ Learn more about the case

See More
See Less
Akveo's case

Elevating CRM with Custom HubSpot Sales Dashboard

Our other client, a SaaS startup, that offers collaborative tools for design and engineering teams, was on a quest to supercharge their sales efforts. Traditional CRM systems were limited and not customizable enough. The company sought a solution that could tailor HubSpot to their workflow and analytics needs.

The scope of work

Charged with the task of going beyond standard CRM functions, our team turned to Retool. We wanted to redefine how sales teams interact with their CRM. 

By integrating advanced analytics, custom metrics, and a user-friendly interface, our developers provided a solution that transformed data into a strategic asset.

In 40 hours, three informative dashboards were developed, containing the most sensitive data related to sales activities. These dashboards enable our customer to analyze sales and lead generation performance from a different perspective and establish the appropriate KPIs.

→ Learn more about the case

See More
See Less
Akveo's case

Retool for Sales and CRM Integration

See More
See Less
Akveo's case

Building a PDF Editor with Low-Code

Our client, a leading digital credential IT startup, needed a lot of internal processes to be optimized. But the experience with low-code tools wasn’t sufficient. That’s why the company decided to hire professionals. And our team of developers joined the project.

The scope of work

The client has a program that designs and prints custom badges for customers. The badges need to be “mail-merged” with a person’s info and turned into a PDF to print. But what is the best way to do it?

Our developers decided to use Retool as a core tool. Using custom components and JavaScript, we developed a program that reduced employees' time for designing, putting the data, verifying, and printing PDF badges in one application.

As a result, the new approach significantly reduces the time required by the internal team to organize all the necessary staff for the conference, including badge creation.

→ Learn more about the case

See More
See Less
Subscription
Subscribe via Email

Want to know which websites saw the most traffic growth in your industry? Not sure why your SEO strategy doesn’t work?

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

By clicking “Subscribe” you agree to Akveo Privacy Policy and consent to Akveo using your contact data for newsletter purposes

More articles by themes

Cross
Contact us
AnnaRodionEvgenyExpertExpertExpert
Cross
Got any questions?
Our domain expert is here to answer
If you have any questions, feel free to leave me a personal message on LinkedIn. We are here to help.
Thanks for your question
We will contact you soon
We have a problem
Please, check the entered data
Got any questions?