In my angular application, i came up with a situation where ngOnchanges should only be called when the inputs are bound to changes. so, is there a way to stop the execution of ngOnChanges before ngOnInit. Is there a way to accomplish this. Thanks in Advance.
3 Answers
You cannot prevent this behavior, but you can:
Use a Subject :
class Foo implements OnChanges,OnInit,OnDestroy{
onChanges = new Subject<SimpleChanges>();
ngOnInit(){
this.onChanges.subscribe((data:SimpleChanges)=>{
// only when inited
});
}
ngOnDestroy(){
this.onChanges.complete();
}
ngOnChanges(changes:SimpleChanges){
this.onChanges.next(changes);
}
}
Use a boolean property:
class Foo implements OnChanges,OnInit{
initialized=false;
ngOnInit(){
// do stuff
this.initialized = true;
}
ngOnChanges(changes:SimpleChanges){
if(this.initialized){
// do stuff when ngOnInit has been called
}
}
}
Use the SimpleChanges API
You can also check the SimpleChange.isFirstChange() method :
isFirstChange() : booleanCheck whether the new value is the first value assigned.
class Foo implements OnChanges,OnInit{
@Input()
bar:any;
ngOnInit(){
// do stuff
}
ngOnChanges(changes:SimpleChanges){
if(!changes["bar"].isFirstChange()){
// do stuff if this is not the initialization of "bar"
}
}
}
One method I have found that works is based on the fact that the input values all have a previous value property. If the input has not previously been set then that value will be CD_INIT_VALUE (as a string). So you can make a condition that your block of code in ngOnChanges should only run if the previous value is not CD_INIT_VALUE. Here's an example for your case where you're testing ALL the input values:
ngOnChanges(changes: SimpleChanges) {
let initialized: boolean = true;
for (let prop in changes) {
if (changes[prop].previousValue.toString() === 'CD_INIT_VALUE') {
initialized = false;
//we can break here since if any item is not initialized
//we will say the inputs are NOT initialized
break;
}
}
if (initialized) {
//code you want to execute
}
}
There are probably more elegant solutions but I've found this works. This is probably too late to help you but may help others as when I googled this I found this question. The solution was something I figured out from debugging.
ngOnChange, you can tryngAfterViewInit()for example (Respond after Angular initializes the component's views and child views) - mickdevngOnInit(),ngDoCheck()is executed (but it will be executed multiple times). If you are using reactive forms, you can keep ngOnChange and check if the form fields are set (if(this.form.get('yourField').value) ...). Something similar to what you have now. - mickdev