31

I need some jQuery code to run after my Angular component view has initialized to transform number values into stars.

I put the code in the ngAfterViewInit function, but it is not doing what I need it to. I set a break point in the function and I see that most of the HTML of my component has not even loaded by the time ngAfterViewInit function is called. The parts that have not loaded are generated using *ngFor directive.

How can I get my code to run after this directive has generated all of the html on which I need to operate?

Gabe O'Leary
  • 2,010
  • 4
  • 24
  • 41
  • Take a look: http://stackoverflow.com/questions/15458609/execute-function-on-page-load – Belakorr Feb 25 '16 at 00:01
  • Opinions: `componentDidMount` is a much simpler abstraction https://facebook.github.io/react/docs/component-specs.html It will only be called after its been called on children. NgFor is not a concept as you just use simple JavaScript `[].forEach` – basarat Feb 25 '16 at 02:08

2 Answers2

29

I have been using ngAfterViewChecked when I depend on the DOM being ready.

import {Component, AfterViewChecked} from '@angular/core'; 

export class Spreadsheet implements AfterViewChecked{

   ngAfterViewChecked(){

   }
}
TGH
  • 38,769
  • 12
  • 102
  • 135
  • work for me where ngAfterViewInit failed simply because doom isn't ready there – baaroz Nov 20 '16 at 12:08
  • 22
    Please keep in mind that `ngAfterViewChecked` can be called more than one time. – Michał Pietraszko Dec 06 '16 at 13:58
  • 1
    I have been doing it this way as well, since I need some code to execute after some HTML elements have been loaded in the template's ngFor. Clearly it is not the best solution, as I now have at least two flags (eg. componentsInitialized, searchComponentsInitialized) to make sure I only execute the corresponding code once in the ngAfterViewChecked. I really am wondering what the correct way to do this would be. – Jort Jan 30 '17 at 15:47
  • 1
    @Jort I also use flags in ngAfterViewChecked - as it gets called often during initialization. But... found a better way. I use ViewChildren, which returns a QueryList. I subscribe to the 'changes' property - when the ngFor completes, the queryList of ngFor's children will trigger the Change subscription. I check if the required amount of elements are in the queryList, and do whatever I need then! – Drenai Jul 03 '18 at 20:01
  • legendddddd, although Michal is right, it does get called a couple of times, so make sure to add some additional null ref checks – WtFudgE Aug 06 '20 at 05:12
25

When does ngAfterViewInit get called?

ngAfterViewInit() should be called after a component's view, and its children's views, are created. I tested this, and found that children's ngAfterViewInit()s are called before the parent's ngAfterViewInit().

When you say "most of the HTML of my component has not even loaded", what do you mean by "loaded"? Is the HTML in the child component's template, or is it being loaded (or generated) by some other means?

How can I get my code to run after this directive has generated all of the html on which I need to operate?

It would help to see the directive code. If the directive somehow generates HTML that is not contained in Angular templates, then you may need to manually trigger an event (e.g., using an output property) to notify the parent when rendering has completed. Or you could use setTimeout() (but that would not be reliable).

I need some jQuery code to run after my Angular component view has initialized to transform number values into stars.

Where are you getting these number values from? If they are dynamically loaded from a server, you could trigger an event when the data arrives, and update the view at that point.

Also, why not write a component that takes a number as an input property and generates stars using NgFor?

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • what we need to use other than setTimeout() to make sure that ngAfterViewInit() JQuery bindings are executed after the Component view rendered.. – Ganesh Oct 19 '18 at 06:34