When is ngDoCheck triggered

The official docs don’t tell much about this lifecycle hook:

Detect and act upon changes that Angular can’t or won’t detect on its own.

Called during every change detection run, immediately after ngOnChanges() and ngOnInit() .

So we know that it’s triggered after ngOnChanges and ngOnInit but is the component being checked or not when it’s triggered? To answer that question, we need to first define “component check”. The article Everything you need to know about change detection in Angular states that there are three core operations related to component change detection:

Besides these core operations Angular triggers lifecycle hooks as part of change detection. What is interesting is that the hooks for the child component are triggered when the parent component is being checked. Here is the small example to demonstrate that. Suppose we have the following components tree:

ComponentA

ComponentB

ComponentC

So when Angular runs change detection the order of operations is the following:

Checking A component:

- update B input bindings

- call NgDoCheck on the B component

- update DOM interpolations for component A



Checking B component:

- update C input bindings

- call NgDoCheck on the C component

- update DOM interpolations for component B



Checking C component:

- update DOM interpolations for component C

If you read the article on change detection I referenced above you will notice that it’s a bit abridged list of operations, but it will do for the purpose of demonstrating when ngDoCheck is triggered.

You can see that ngDoCheck is called on the child component when the parent component is being checked. Now suppose we implement onPush strategy for the B component. How does the flow change? Let’s see:

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:

- update C input bindings

- call NgDoCheck on the C component

- update DOM interpolations for component B



Checking C component:

- update DOM interpolations for component C

So with the introduction of the OnPush strategy we see the small condition if (bindings changed) -> checking B component is added before B component is checked. If this condition doesn’t hold, you can see that Angular won’t execute the operations under checking B component . However, the NgDoCheck on the B component is still triggered even though the B component will not be checked. It’s important to understand that the hook is triggered only for the top level B component with OnPush strategy, and not triggered for its children — C component in our case.

So, the answer to the question:

I have used OnPush strategy for my component, but the ngDoCheck lifecycle hook is still triggered. Is the strategy not working?

is — the strategy is working. The hook is triggered by design and the next chapter shows why.