Reputation: 2209
I have a method that I need to execute after DOM has been updated with a data. When I run my method immediately after setting the property (bound to a template), the script does receive empty div in DOM because Angular 2 probably hasn't updated it yet.
Strangely, invoking timeout fixes this issue, but it feels bad. How could I make sure that my method is executed after Angular 2 updates template?
My component:
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import 'rxjs/add/operator/switchMap';
import { CodeExample } from './code-example.class';
import { CodeExampleService } from './code-example.service';
@Component({
selector: 'code-example-detail',
templateUrl: 'code-example-detail.component.html',
})
export class CodeExampleDetailComponent implements OnInit {
@Input()
codeExample: CodeExample;
constructor(
private codeExampleService: CodeExampleService,
private route: ActivatedRoute,
private location: Location,
) {
}
ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.codeExampleService.getCodeExample(+params['id']))
.subscribe((codeExample: CodeExample) => this.processRequest(codeExample));
}
processRequest(codeExample: CodeExample): void{
this.codeExample = codeExample;
console.log(codeExample.title); // correct data is returned
//setTimeout(() => this.doSomethingWithDom(), 0); fixes the problem
//this.doSomethingWithDom(); // Does NOT work because template is not updated
}
doSomethingWithDom(): void{
// do something with dom here
}
}
Upvotes: 0
Views: 861
Reputation: 12596
maybe you add combine lifecycle ngAfterViewChecked()
with a property like this:
export class CodeExampleDetailComponent implements OnInit, AfterViewChecked {
// other properties
private doIt = false;
processRequest(codeExample: CodeExample): void{
// other code
this.doIt = true;
}
doSomethingWithDom(): void{
// do something with dom here
this.doIt = false;
}
ngAfterViewChecked() {
if (this.doIt) this.doSomethingWithDom();
}
}
note that ngAfterViewChecked()
will call in every tick.
Upvotes: 1
Reputation: 883
Try this,
this.route.params
.switchMap((params: Params) => this.codeExampleService.getCodeExample(+params['id']))
.subscribe((codeExample: CodeExample) => {
this.processRequest(codeExample);
this.doSomethingWithDom();});
}
Upvotes: 0