how to stop ngOnChanges Called before ngOnInit()
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.
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() : boolean
Check 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"
}
}
}