I am trying to add a custom validator to an input, but when I do so it triggers an ExpressionChangedAfterItHasBeenCheckedError error saying something changed from TRUE to FALSE.
I traced the problem down to the line below:
ngOnInit(): void {
this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()]));
}
If I remove the TabValidator.ipaddress() then the error disappears. Similarly if my validator forces return of 'null' then the error goes away. My validator is as follows:
private static _ipaddress(address: string): any {
console.log('checking ip address: '+address+' valid: '+ip.isV4Format(address)+' is null: '+(address === null ? 'yes' : 'no'));
if (!ip.isV4Format(address)) { return { 'wrongFormat': true }; }
console.log('returning null');
return null;
}
public static ipaddress(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
console.log('validator returning: '+TabValidator._ipaddress(control.value));
return TabValidator._ipaddress(control.value);
};
}
From the console log it appears that the validator is returning the same value each time.
Can someone explain what is going wrong here? I can't explain what variable is changing from 'true' to 'false' since there are no booleans involved in the lines above. How can the validator return different values without appearing in my console log?
I read one SO questions about not doing things in ngOnInit but that seems like a red herring.
UPDATE: I tried:
ngOnInit(): void {
Promise.resolve().then(() => {
this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()]));
});
}
and also
ngOnInit(): void {
setTimeout(() => this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()])), 10);
}
but then error changes to:
ERROR Error: Cannot find control with name: 'gateway'
SOLUTION:
I traced this down to a bug - using reactive forms + validators + ngb tabs. Adding the validator to the control on a tab causes the error. Only solution is to change to template forms.
*ngIf
blocking the rendering of some component and so on...I ran into this problem several times and it was always because something was not correct with my code / components rendering order. – Scherman*ngIf*
could be an issue, but there are a lot of things that cause that error and as I said, mostly because of the ordering of components rendering. There is too less code to tell you where is the issue. If you can reproduce in a plunker (I recommend nowadays stackblitz.com) would be very helpful... – SchermanExpressionChangedAfterItHasBeenCheckedError
error – Halsted