Notice when angular component and its children are rendered

Issue

I have an angular component that has another component which has also another component. So, the components are nested.

I want to notice when all subcomponent views are rendered completely.
I tried all life cycle hooks like

ngAfterContentChecked

and

ngOnChanges

but none of them was called. Is it possible to recognize the rendering?

EDIT:

My view will be changed dynamically. Therefore, I need to know this not just at the beginning.

My components look like:

Parent view:

<child-1></child-1>

Child-1 view:

<child-2><child-2>

Solution

You can be sure that when the ngAfterViewInit in the deepest and last child component has been called, all the ancestors are rendered as well.

Which basically means, if you have a structure like this:

<parent>
  <child-1>
    <child-2></child-2>
    <child-3></child-3>
  </child-1>
</parent>

you can be sure that when child-3 calls the ngAfterViewInit, everything from the tree is rendered:

@Component({
  selector: 'child-3'
}) 
export class Child3Component implements AfterViewInit {
  ngAfterViewInit(): void {
    console.log('all done here');
  }
}

If you want to know when updates are processed through the tree and the template is updated after a cycle, you need to use the ngAfterViewChecked hook. Fun fact though, this is done the other way around. So you only need to listen on the most parent node to find out when it’s done checking.

With the same tree in mind:

@Component({
  selector: 'parent'
}) 
export class ParentComponent implements AfterViewChecked {
  ngAfterViewChecked(): void {
    console.log('all done here');
  }
}

On the other hand, if you want to know after an event has been triggered, if the view has been updated, you can also just use the change detector, or the applicationRef, or a setTimeout:

If this part of code is inside your component

(it shouldn’t be! don’t use directly http from inside a component!)

this.http.get(url).subscribe((data) => {
  this.data = data;

  // method 1:
  setTimeout(() => {
    // view is rendered here
  });


  // method 2:
  this.changeDetectorRef.detectChanges();
  // view is rendered here


  // method 3:
  this.applicationRef.tick();
  // view is rendered here
}); 

Be aware though, if your component (or any parent component) has the changeDetection set to OnPush, you first have to set: this.changeDetectorRef.markForCheck() with any of the methods.

Answered By – Poul Kruijt

Answer Checked By – Mildred Charles (AngularFixing Admin)

Leave a Reply

Your email address will not be published.