AlanObject
AlanObject

Reputation: 9943

Need a callback when it is OK to access the DOM

I have an Angular component that fetches markdown, converts it to HTML, then inserts it into the DOM. After insertion it does some more DOM manipulation. So the template is this:

<div id="fixroot" [innerHTML]="content"></div>

and the component is like this:

    content: string;

    ...

    async getPage(url: string) {
       try { 
           this.content = this.mdToHtml(await this.http.get(url, { responseType: 'text'}).toPromise();
           setTimeout(() => this.fixupDOM(), 400);

    ....

    fixupDom() {
       const el = document.getElementById('fixroot');
       // do stuff to the DOM element that are children of el


The use of setTimeout here is really awful, but without it the fixupDom method doesn't work because the DOM is not ready when the Promise concludes. But it has to go.

What I need is a callback (probably from the HTMLElement el) that calls my routine as soon as the DOM structure is ready. I haven't been able to make anything work. Anyone know the right function?

Upvotes: 0

Views: 78

Answers (2)

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38922

ngAfterContentInit lifecycle hook is called earlier during creation and rendering of component and directive.

You can implement it in your directive and access content to be reflected in the directive's view. For example,

ngAfterContentInit() {
  const el = this.content.nativeElement;
  // mutate el as desired  
}

Upvotes: 0

Nico
Nico

Reputation: 2021

You can try and use the ngAfterViewInit hook that fires after your content has been loaded.

If you use a template reference for your div then you can access it after the ngAfterViewInit fires.

This is the angular way of accessing the DOM which makes it framework agnostic in case you want to run in a web worker etc...

Since you are inserting HTML you made also need to pipe that HTML through a Sanitizer because angular has a sanitizing context due to XSS.

Upvotes: 1

Related Questions