I have an input where user needs to type a longitude. I want to be able to display different error message when user types NaN
or Not-Precise-Enough
value. I'm using FormControl.hasError('ValidatorsName')
to get the errors with validation, but it seems like I cannot differentiate those patterns.
Template:
<mat-form-field class="form-field">
<input matInput placeholder="Logitude" [formControl]="longitude">
<mat-error *ngIf="longitude.hasError('pattern')">
Longitude must be <strong>a number</strong>
</mat-error>
<!-- I want to be able to check patter2 for example -->
<mat-error *ngIf="longitude.hasError('pattern')">
Longitude must have <strong>a minimum of 5 decimal numbers</strong>
</mat-error>
</mat-form-field>
And my Angular code:
this.longitude = new FormControl(this.attraction.longitude, [
// is valid number
Validators.pattern(new RegExp('(\d{1,3})([.|,]{,1})(\d+))','gi')),
// is precise enough
Validators.pattern(new RegExp('(\-{0,1})(\d{1,3})([.|,]{1})(\d{5,13})','i'))
]);
Is there any way to give those patterns an identifier? I'll appreciate any help.
ValidatorFnlinkA function that receives a control and synchronously returns a map of validation errors if present, otherwise null. interface ValidatorFn { (control: AbstractControl<any, any>): ValidationErrors | null }
Parameters. The function or array of functions that is used to determine the validity of this control synchronously.
required : Validator that requires controls to have a non-empty value. It also validates that the value matches the input type. For example, if the input is of “email” type, then the input will be valid if it's not empty and if the value is of email type.
The creating an async validator is very similar to the Sync validators. The only difference is that the async Validators must return the result of the validation as an observable (or as Promise). Angular does not provide any built-in async validators as in the case of sync validators.
Unfortunately it is not possible to give Validators a custom identifier.
As Dawid Zbinski mentioned in the comments that multiple errors with the same error (e.g.: 'pattern') getting override, I updated my answer.
Create a custom validator which gets passed the regex and a predefined error as an argument:
regexValidator(regex: RegExp, error: ValidationErrors): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
if (!control.value) {
return null;
}
const valid = regex.test(control.value);
return valid ? null : error;
};
}
and use it like this:
this.longitude = new FormControl('', [
this.regexValidator(new RegExp('^[0-9]+$'), {'number': ''}),
this.regexValidator(new RegExp('^.{5,}$'), {'precision': ''})
]);
<mat-form-field class="form-field">
<input matInput placeholder="Logitude" [formControl]="longitude">
<mat-error *ngIf="longitude.hasError('number')">
Longitude must be <strong>a number</strong>
</mat-error>
<!-- I want to be able to check patter2 for example -->
<mat-error *ngIf="longitude.hasError('precision')">
Longitude must have <strong>a minimum of 5 decimal numbers</strong>
</mat-error>
</mat-form-field>
I also updated the stackblitz demo: https://stackblitz.com/edit/angular-dvwcj3?file=app%2Fhello.component.ts
OLD ANSWER:
But the PatternValidators
are returning unique ValidatonErrorObjects
.
When you check out the source code from the pattern validator at the official angular repo you can see they always return the regex inside the error object.
return (control: AbstractControl): ValidationErrors | null => { if (isEmptyInputValue(control.value)) { return null; // don't validate empty values to allow optional controls } const value: string = control.value; return regex.test(value) ? null : {'pattern': {'requiredPattern': regexStr, 'actualValue': value}}; };
With this in mind you can easily create two getter methods inside your component.ts
file. And they differ between the two regular expressions. In this example they simply check if an unique substring matches the regular expression. For sure they are other ways to handle this.
get numberError() {
if (this.longitude && this.longitude.hasError('pattern')) {
return this.longitude.getError('pattern').requiredPattern.indexOf('(\d+)') !== -1
}
return false;
}
get preciseError() {
if (this.longitude && this.longitude.hasError('pattern')) {
return this.longitude.getError('pattern').requiredPattern.indexOf('(\-{0,1})') !== -1
}
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With