My angular 2 application uses reactive forms.
I initialize the following FormGroup
in one of my components:
ngOnInit() {
...
this.addressForm = this.formBuilder.group({
address: this.formBuilder.control({
placeId: this.address.placeId,
description: this.address.description
}, addressValidator)
});
}
Here is the definition for the addressValidator
:
import {AbstractControl} from '@angular/forms';
export function addressValidator(control: AbstractControl) {
const {placeId} = control.value;
return (placeId !== undefined && placeId !== null && placeId !== '') ? null : {addressValidator: {emptyPlaceId: true}};
}
Here is how I try to check whether the form control i.e. address
is in error:
addressFormErrors(error: string) {
return this.addressForm.hasError(error, ['address', 'addressValidator']);
}
Here is the template calling the addressFormErrors method:
<form [formGroup]="addressForm" (ngSubmit)="updateAddress()" novalidate>
<div class="form-group" [ngClass]="getFeedbackClasses(addressForm, 'address', submitted)">
<div class="input-group">
<input type="text"
formControlName="address"
placeholder="{{'ADDRESS_FORM.NEW_ADDRESS' | translate}}"
[ngbTypeahead]="chooseAddress"
[inputFormatter]="addressFormatter"
[resultFormatter]="addressFormatter"
autocomplete="off"
class="form-control"
[ngClass]="formControlStatusClass(addressForm, 'address', submitted)">
</div>
<div [hidden]="addressForm.valid || !submitted">
<div *ngIf="addressFormErrors('emptyPlaceId')" class="form-control-feedback form-control-label">{{'ADDRESS_FORM.ADDRESS_REQUIRED' | translate}}</div>
</div>
</div>
...
</form>
Here is the method invoked upon form submission:
updateAddress() {
this.submitted = true;
if (this.addressForm.valid) {
const placeId = this.addressForm.controls['address'].value['placeId'];
this.userAccountService.updateAddress(placeId)
.subscribe(() => this.router.navigate(['/dashboard/useraccount']));
}
}
edit: Gunter is right: the validator does indeed return the error object on value change. The issue is elsewhere: it is in the addressFormErrors
method not returning true - probably due to some mistake in the property path specification.
Can someone please help?
Adding async validators to reactive formslink To use an async validator in reactive forms, begin by injecting the validator into the constructor of the component class. Then, pass the validator function directly to the FormControl to apply it.
The issue is elsewhere: it is in the addressFormErrors method not returning true - probably due to some mistake in the property path specification. Can someone please help? Validators are supposed to be executed when the values change, not on submit. You're right Günter.
Let's now quickly summarize everything that we have learned about custom form validators: a custom validator is a function that validates the value of a form field according to a business rule, such as form example the field is mandatory or the password needs to have a certain strength
edit: Gunter is right: the validator does indeed return the error object on value change. The issue is elsewhere: it is in the addressFormErrors method not returning true - probably due to some mistake in the property path specification. Can someone please help? Validators are supposed to be executed when the values change, not on submit.
When using a custom validator directive with FormGroup and mat-error, errors are not displayed and behavior is unpredictable. Moving between fields may display one or more errors, some are duplicated. Other fields not in the FormGroup are also affected.
Changing the returned error object from
{addressValidator: {emptyPlaceId: true}}
to:
{emptyPlaceId: true}
and the addressFormErrors
from
addressFormErrors(error: string) {
return this.addressForm.hasError(error, ['address', 'addressValidator']);
}
to:
addressFormErrors(error: string) {
return this.addressForm.controls['address'].hasError(error);
}
fixed it.
However, please note that this not an altogether satisfactory solution as I am no longer able to specify different error types on the same validator.
I would be grateful if someone could explain how to properly use the hasError method with custom validators.
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