Reputation: 1515
How can I get my custom mat-error
to trigger immediately? I know there is an example in the Angular docs, but couldn't get that to work. My validation is not for empty
nor of a certain type
, for example email
.
I would like my error to display when I do a search in my drop-down field and no records were found. A normal <div>
below the item triggers immediately on *ngIf
, but not the mat-error
. I have also tried updating the mat-error with .innerHTML
, but the field does not exist. I am sure it is because Angular has not yet created it.
Here is my HTML:
<mat-form-field>
<input type="text" placeholder="Customer Search" id="CustomerId" name="CustomerId" aria-label="Number" matInput [formControl]="myCustomerSearchControl"
[matAutocomplete]="auto" (keyup)="onCustomerSearch($event)"
required [errorStateMatcher]="matcher">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="setLoadId($event)">
<mat-option *ngFor="let customer of customerArray" [value]="customer.Display">
{{ customer.Display }}
</mat-option>
</mat-autocomplete>
<mat-error id="customer-error" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</mat-error>
</mat-form-field>
<div>
<span class="errorMessage" *ngIf="noCustomersFound.value">
{{noCustomersFound.message}}
</span>
</div>
Here is my method in my .ts file and some stuff I have tried:
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
if (data.length < 1) {
this.noCustomersFound.value = true;
this.noCustomersFound.message = 'No match found.'
document.getElementById('customer-error').innerHTML = 'No match found.';
} else {
this.noCustomersFound.value = false;
this.noCustomersFound.message = '';
}
this.customerArray = data;
});
}
Upvotes: 2
Views: 1819
Reputation: 52
First, you need a custom validator.
You can generate directive which will be used for validating FormControl in angular by typing this command in your CLI:
ng g directive customValidator
That directive should have function which looks similar to this:
//make sure to post this code below the class closing curly brackets.
export function customerSearchIsEmpty(searchResultsLength): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const isValid = searchResultsLength ? searchResultsLength > 0 : false;
return isValid ? null :
{ 'customerSearchIsEmpty': { value: control.value } }; };}
Once your FormControl is created, you should dynamically add your new validator:
this.registeredForm.controls['myCustomerSearchControl'].setValidators([customerSearchIsEmpty(null)])
In the TS file where your onCustomerSearch function is, you should add one more function:
myCustomerSearchControlIsInvalid() {
this.myCustomerSearchControl.updateValueAndValidity();
//instead of registeredForm, use your FormGroup name.
if (this.registeredForm.hasError('customerSearchIsEmpty')) {
this.noCustomersFound.message = 'No customer found'; //or any other message
} else {
return false;
} return true;
}
You should modify your to react to the myCustomerSearchControlIsInvalid() function's result:
<mat-error *ngIf="myCustomerSearchControlIsInvalid()">
{{noCustomersFound.message}}
</mat-error>
And, in the end you should add this line of code in your onCustomerSearch() function.
onCustomerSearch(search) {
let searchObject = new SearchObject();
searchObject.Entity = 'Customer';
searchObject.SearchString = search.key;
searchObject.SearchClauses = [{Column: 'sCustomerName'}];
searchObject.DisplayColumn = 'sCustomerName';
this.loadDataService.searchByEntity(searchObject)
.subscribe(data => {
customerSearchIsEmpty(data.length);
this.customerArray = data;
});}
I hope this helps.
Upvotes: 1