Reputation: 1542
I want a way to remove a specific error from a form control and not clear all error.
control.setError({'firstError': true})
and to remove that specific error like
control.removeError({'firstError}) and not control.setError({null})
I tried
control.setError({'firstError': false})
but didn't work.
Any help. Thanks
angular 4.1.1
Upvotes: 62
Views: 88772
Reputation: 1804
for clear all validations you can use markAsUntouched
function like below.
for example for form group controls:
for (let controlsKey in this.formGroup.controls) {
let control = this.formGroup.controls[controlsKey];
control.markAsUntouched();
}
Upvotes: 4
Reputation: 6325
You can remove like this:
control.setErrors({'firstError': null})
Upvotes: 33
Reputation: 857
I was having this bug caused by using *ngIf to show some controls. I want to delete ALL errors and start from scratch this works:
Object.keys(this.myForm.controls).forEach(controlName => {
if (controlName != "search") {
let control = that.myForm.controls[controlName];
if (control.errors) {
let errorKeys = Object.keys(control.errors);
errorKeys.forEach(key => {
delete control.errors[key];
})
}
control.setErrors(null);
this.options[controlName + "Error"] = null;
}
});
in my code I want to leave the "search" control alone, and I also clear the error strings I save in this.options.{controlName}Error
Upvotes: 0
Reputation: 1365
control.setErrors({'firstError': null});
Will not working anymore. You need to use a helper method. Copied from https://github.com/angular/angular/issues/21564#issuecomment-480569715
public static removeErrors(keys: string[], control: AbstractControl) {
if (!control || !keys || keys.length === 0) {
return;
}
const remainingErrors = keys.reduce((errors, key) => {
delete errors[key];
return errors;
}, { ...control.errors });
control.setErrors(remainingErrors);
if (Object.keys(control.errors || {}).length === 0) {
control.setErrors(null);
}
}
Upvotes: 4
Reputation: 696
You can remove error with:
control.setErrors({'firstError': null});
control.updateValueAndValidity();
Upvotes: 58
Reputation: 2947
I am using Dynamic Forms and I wanted to clear the error of one component from another. I tried .setErrors() method but it was not working. The working solution for me is listed below.
clearControlError( control: AbstractControl ): void {
const err = control.errors;
if (err) {
delete err['timeNotValid'];
if (!Object.keys(err).length) {
control.setErrors(null);
} else {
control.setErrors(err);
}
}
}
now I can clear error of any AbstractControl type control by passing it to the function like this.
this.clearControlError(this.formBase.parent.get('startTime'));
or
this.clearControlError(this.form.controls['startTime']);
Upvotes: 5
Reputation: 101
I came from this github issue and try this little workaround 😬
Using Destructuring assignment
if ( control.hasError('errorToRemove') ) {
const { errorToRemove, ...errors } = control.errors;
control.setErrors(errors);
control.updateValueAndValidity();
}
You can also try the omit or pick lodash
functions, to respectively omit or pick a series of errors that you can set to the control later.
const errors = pick(control.errors, ['onlyErrorsToKeep']);
control.setErrors(errors);
control.updateValueAndValidity();
const errors = omit(control.errors, ['allErrorsToRemove']);
control.setErrors(errors);
control.updateValueAndValidity();
Upvotes: 9
Reputation: 379
Much has already been stated in other posts to this question (e.g. delete the error property (which still leaves the control flagged as invalid
), issues with updateValueAndValidity()
in changeHandlers
(infinite loop) etc). Putting it all together I now use the below small function, which leaves other errors untouched and resets the invalid flag if no other errors remain:
removeFormControlError(control: AbstractControl, errorName: string) {
if (control?.errors && control?.errors[errorName]) {
delete control.errors[errorName];
if (Object.keys(control.errors).length === 0) {
control.setErrors(null);
}
}
}
Upvotes: 17
Reputation: 2041
If we are dynamically adding and removing errors, as of Angular 8, the above examples simply don't work. I'm adding errors based upon the state of other controls. i.e. I have two customers defined with the same email address. This is the only solution I could find that actually works.
tap(duplicateError => {
/* Note to future self...
* I'm beginning to hate AbstractControl.errors.
* The email control can have multiple errors (required, email, and duplicate);
* The ONLY way to clear an error is to not have it in the object that is passed to the setErrors call.
* You CANNOT pass null or undefined! It will still be evaluated as an error!
* This is also true if there are NO errors AT ALL. You cannot pass setErrors({}) or the control will be
* invalid, even though there are no errors! You must call setErrors(null);
* This is stupid, but it's the only way it works.
* This code is concerned with setting/removing the duplicate error.
*/
const email = this.form.get('email');
// Clone the existing errors
const existingErrors = { ...email.errors };
// Ensure that duplicate error is removed (we're in the change handler for the duplicate error)
delete existingErrors.duplicate;
if (duplicateError) {
// We have a new duplicate error, so add it.
email.setErrors({ ...existingErrors, duplicate: duplicateError.errorMessage });
} else if (Object.keys(existingErrors).length === 0) {
// We have NO errors, so pass null
email.setErrors(null);
} else {
// We have existing errors, but no new duplicate error. Pass the existing errors.
email.setErrors(existingErrors);
}
this.changeDetector.markForCheck();
})
Upvotes: 3
Reputation: 865
First, you should check your field for has this error. next, remove it. And for end you are need to update all errors in your controll.
Something like this in validator function:
if (control.hasError('firstError')) {
delete control.errors['firstError'];
control.updateValueAndValidity();
}
Regards.
Upvotes: 51
Reputation: 8484
Unfortunately, it didn't work for me. I simply used updateValueAndValidity() which is used to re-calculate the value and validation.
The below is my validator function which validates my grossWeight
.
validateWeights(formGroup) {
let netWeight = formGroup.get('netWeight');
let grossWeight = formGroup.get('grossWeight');
if (parseFloat(netWeight.value) > parseFloat(grossWeight.value)) {
grossWeight.setErrors({ 'customError': true });
netWeight.setErrors({ 'customError': true });
} else {
if(netWeight.errors && netWeight.errors['customError']) {
netWeight.updateValueAndValidity();
}
if (grossWeight.errors && grossWeight.errors['customError']) {
grossWeight.updateValueAndValidity();
}
}
}
Upvotes: 5