You seem to be mixing two form syntaxes: form-driven forms and model-driven forms.
Since you are declaring a form model in your class with FormBuilder
, I assume that you want a model-driven form.
This means that your fields do not need attributes such as [(ngModel)]
or #EmailAddress
.
Instead of this:
<input type="email" [(ngModel)]="user.EmailAddress" required #EmailAddress="ngModel">
Write this:
<input type="email" formControlName="email">
ALL of your validators must be declared in FormBuilder. Not only matchingEmailsValidator
, but also required
:
this.Form = fb.group({ email: ['', Validators.required], confirmEmail: ['', Validators.required] }, { validator: this.matchingEmailsValidator('email', 'confirmEmail') });
Now you can access the field with the following syntax:
// In the class this.Form.get('email').value this.Form.get('email').errors
{{ Form.get('email').value }} {{ Form.get('email').errors }}
You can use these syntaxes to display errors. For instance:
<input type="email" formControlName="email"> <p *ngIf="Form.get('email').dirty && Form.get('email').errors.required"> This field is required. </p>
In the above example, an error message appears if the email
field has been touched (i.e. the user tried to enter something) And a required
error is present.
You can also verify that your validation rules are being followed by checking the layout of the form using your browser tools. Angular should add tags .ng-invalid
or .ng-valid
to tags <input>
, which have validation rules.
Finally, regarding your question, check the correspondence by email when blurring . You cannot postpone Angular validation, this will happen in real time (as the user enters). But you can wait for the blur event to display errors .
Combining this last tip with my previous example, here is how you might be mistaken if the email field is empty and it has lost focus (blur event):
<input type="email" formControlName="email" (blur)="displayErrors=true"> <p *ngIf="displayErrors && Form.get('email').dirty && Form.get('email').errors.required"> This field is required. </p>
UPDATE (01-FEB-2017) after the publication of Euridice this Plunkr :
- You still have wayyyyy for the great validation code in your template. As I said, ALL VALIDATORS must be declared in the FORM MODEL (with
FormBuilder
). More specific:- The
pattern="..."
attribute in the email
field should be replaced with Validators.pattern()
in the form model. - What is the
validateEqual="email"
attribute in the confirmEmail
field? You are not using anything.
- The main problem is that your test displays an error message:
*ngIf="displayErrors && !Form.get('email').valid && Form.get('email').error.mismatch"
.- First of all, the
errors
property with "s", not error
. - In addition, your custom validator sets an error in the form itself , and not in the email field. This means that you should get a custom error
mismatch
of Form.errors.mismatch
, the NOT Form.get('email').errors.mismatch
.
Here's the updated, working Plunkr: https://plnkr.co/edit/dTjcqlm6rZQxA7E0yZLa?p=preview