I have a dropdown, and based on the selected option, I display specific form controls. For the dropdown option value2, I display an error message: "Please provide either the Body or both Username and Password," indicating that one of these fields is required in order to save the form.The issue is that when I select option value1 or value3 from the dropdown, the error message (h6) still appears on the form, and the atLeastOne validation error persists. I am unable to reset or clear this error, even after changing the dropdown value.
Template Code:
<form [formGroup]="form">
<h2 style="display: inline-block;">{{action}} {{operationName}}</h2>
<h6 style="color: red; display: inline-block;margin: 0;margin-left: 0.3rem;"
*ngIf="isSaveDisabled()">
(Required Field is/are missing)
</h6>
<h6 style="color: red; display: inline-block;margin: 0;margin-left: 0.3rem;"
*ngIf="form.getError('atLeastOne') != null">
(Please provide either the Auth Request Body or both Username and Password)
</h6>
<ng-container [ngSwitch]="column['type']">
<!-- Text Input -->
<!-- Dropdown Input -->
<select *ngSwitchCase="'dropdown'" id="{{column['label']}}"
formControlName="{{column['label']}}"
(change)="handleDropdownChange(column['label'])">
<option value="">ALL</option>
<option *ngFor="let item of column['options']" [value]="item">
{{item}}
</option>
</select>
</ng-container>
</form>
ts file:-
ngOnInit() {
this.columns = [
{
label: 'Type',
value: '',
type: 'dropdown',
required: true,
options: ['value1', 'value2', 'value3'],
},
{
label: 'Body',
value: '',
type: 'inputTextArea',
required: true,
},
{
label: 'Username',
value: '',
type: 'inputTextField',
required: true,
},
{
label: 'Password',
value: '',
type: 'inputTextField',
required: true,
},
];
this.columns?.forEach((column) => {
const control = this.fb.control(
column.value,
column.required ? Validators.required : null
);
this.form.addControl(column.label, control);
});
if (value === 'value2') {
console.log('this is called');
this.form.get('Username')!.clearValidators();
this.form.get('Password')!.clearValidators();
this.form.get('Body')!.clearValidators();
this.form.setValidators(this.conditionalValidator());
this.form.updateValueAndValidity();
this.cdr.detectChanges();
}
console.log('Form after adding controls: ', this.form.value);
}
}
handleDropdownChange(value: string): void {
console.log('Handling Option2 change:', value);
console.log('Before:', JSON.stringify(this.form.errors, null, 2));
console.log('1 ' + this.form.getError('required'));
// Clear errors on each form control
Object.keys(this.form.controls).forEach((key) => {
const control = this.form.get(key);
console.log('Control error:', control?.errors);
if (control) {
control.setErrors(null);
control.updateValueAndValidity();
}
});
console.log('2 ' + this.form.getError('required'));
// On dropdown change we have to clear the errors
console.log('1 ' + this.form.getError('atLeastOne'));
this.form.setErrors({ atLeastOne: 'good' });
this.form.updateValueAndValidity();
console.log('2 ' + this.form.getError('atLeastOne'));
this.form.get('atLeastOne')?.setErrors({
atLeastOne: 'Atasdsd.',
});
this.form.updateValueAndValidity();
this.cdr.detectChanges();
this.clearRequiredValidators();
// this.form.updateValueAndValidity();
console.log('Form errors after:', JSON.stringify(this.form.errors, null, 2));
this.populateForm(value);
}
conditionalValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const body = control.get('Body');
const username = control.get('Username');
const password = control.get('Password');
if (body && authRequestBody.value.length > 0) {
return null;
}
if (
username &&
password &&
username.value.length > 0 &&
password.value.length > 0
) {
return null;
}
return { atLeastOne: 'At least one field has to be provided.' };
};
}
Console prints:-
Before: {
"atLeastOne": "At least one field has to be provided."
}
consumer-details.component.ts:418 1 undefined
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: {required: true}
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:422 Control error: null
consumer-details.component.ts:432 2 undefined
consumer-details.component.ts:434 1 At least one field has to be provided.
consumer-details.component.ts:437 2 At least one field has to be provided.
consumer-details.component.ts:446 Form errors afte: {
"atLeastOne": "At least one field has to be provided."
}
h6 message is getting displayed even after changing dropdown values. I am using custom validator function