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
You cannot prevent this behavior, but you can:
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);
}
}
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
}
}
}
SimpleChanges
APIYou 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"
}
}
}
In case it helps anyone here's an example of how I implemented the isFirstChange()
solution suggested by @n00dl3 into my AngularJS app:
this.$onChanges = (changes) => {
if (!changes.value.isFirstChange()) {
// do stuff
}
};
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.