I have a little problem and I am not sure what the issue is, perhaps someone here can help?
In my Angular App I have a component that contains a child directive that is attached to form inputs. This child directive takes an @Input()
which is a string array called errors
.
So in the parent HTML template we have something like so...
<!-- parent-component.component.html file -->
<input type="text" myDirectiveName [errors]="errors">
I want it so that when the errors
sting array value changes this change is detected in the directive. I always thought that @Inputs()
are treated as Observables so in the parent component I did the following (I have reduced the code for simplicity)
@Component({
selector: 'parent-component',
templateUrl: './parent-component.component.html',
styleUrls: ['./parent-component.component.scss']
})
export class ParentComponent implements OnInit {
// declare the errors string array
errors = [];
ngOnInit(): void {
this.getErrors();
}
getErrors(): void {
setInterval(() => {
if(this.errors.length > 3) {
this.errors.length = 0;
} else {
this.errors.push('This is an error');
}
}, 1000);
}
}
I thought this would automatically update in my @Input
but it does not, even though if I write the errors array to parent interface in the parent-component.component.html
file using {{ errors | json }}
I can see the array increase and shrink over time.
So, I thought I will use ngOnChanges
within my Directive to capture the changes, here is some simplified code:
@Directive({
selector: '[myDirectiveName]'
})
export class errorDirective implements OnInit, OnChanges {
@Input() errors: string[];
ngOnInit() {
// do stuff...
}
ngOnChanges(simpleChange: any) {
console.log(simpleChange);
}
}
Using this code I can see the changes being output as the Input is initialized but not when I change the value later in the parent. Is the problem how I am changing my errors array using setTimeout
? I'm really confused why I can't capture the changes via the Directive Input()
? If anyone can help me understand what I am doing wrong I would be most appreciative.
Also if my wording is confusing or wrong please add a comment and I shall reword/rework this question.
Errors is an array, which is an object i.e. immutable. for inputs to detect changes in ngonchanges you have to assign a new reference to array. one of the way is to create shallow copy by using spread operator where ever are are adding or removing any value from array.
this.errors.push('new error');
this.errors = [...this.errors];