Reputation: 14610
New to Angular and trying to add a custom email validator that will go to my server and check if the email address is already in use.
But can't seem to get the error message displaying on form. Here is how I'm testing it before I attempt to hit the server.
FYI - the "emailMatchValidator()" is called but I can't get it to display any kind of error message on the form!
Maybe I should try something other than .touched!
ngOnInit() {
this.createRegisterForm();
}
createRegisterForm() {
this.registerForm = this.fb.group({
gender: ['male'],
email: ['', [Validators.required, Validators.email]],
username: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(10)]],
knownAs: ['', Validators.required],
dateOfBirth: [null, Validators.required],
city: ['', Validators.required],
country: ['', Validators.required],
password: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(8)]],
confirmPassword: ['', Validators.required]
}, {
validator: [this.passwordMatchValidator, this.emailMatchValidator]
});
}
emailMatchValidator(g: FormGroup) {
return g.get('email').value !== '[email protected]' ? null : {
emailExists: true
};
}
<div class="form-group">
<input type="email"
[ngClass]="{'is-invalid': registerForm.get('email').errors && registerForm.get('email').touched}
|| registerForm.get('email').touched && registerForm.hasError('emailExists')"
class="form-control"
formControlName="email"
placeholder="Email">
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('required')">
Email is required
</div>
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('email')">
Invalid email address
</div>
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('emailExists')">
Email address already in use
</div>
</div>
Upvotes: 1
Views: 10181
Reputation: 15041
Made some changes:
You had applied the validation to the complete form, i changed that to the email field only email: ['', [Validators.required, Validators.email, this.emailMatchValidator]],
;
Added the email field value & email field status to the screen to see the validation in action
relevant HTML:
<form class="form-group" [formGroup]='registerForm'>
<input type="email"
[ngClass]="{'is-invalid': registerForm.get('email').errors && registerForm.get('email').touched}
|| registerForm.get('email').touched && registerForm.hasError('emailExists')"
class="form-control"
formControlName="email"
placeholder="Email">
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('required')">
Email is required
</div>
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('email')">
Invalid email address
</div>
<div class="invalid-feedback" *ngIf="registerForm.get('email').touched && registerForm.get('email').hasError('emailExists')">
Email address already in use
</div>
</form>
<hr/>
<b>email value:</b> {{registerForm.controls.email.value}} <br/>
<b>email status:</b> {{registerForm.controls.email.status}}
relevant TS:
import { Component } from '@angular/core';
import { FormBuilder, Validators, FormGroup, AbstractControl } from '@angular/forms'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
constructor(private fb: FormBuilder) { }
registerForm;
ngOnInit() {
this.createRegisterForm();
console.log(this.registerForm);
}
createRegisterForm() {
this.registerForm = this.fb.group({
gender: ['male'],
email: ['', [Validators.required, Validators.email, this.emailMatchValidator]],
username: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(10)]],
knownAs: ['', Validators.required],
dateOfBirth: [null, Validators.required],
city: ['', Validators.required],
country: ['', Validators.required],
password: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(8)]],
confirmPassword: ['', Validators.required]
}
/*, {
validator: [this.passwordMatchValidator, this.emailMatchValidator]
}
*/
);
}
passwordMatchValidator() {
/* some implementation */
}
emailMatchValidator(control: AbstractControl) {
if (control.value !== '[email protected]') {
return false;
} else {
return { emailExists: true };
}
}
}
working stackblitz here
Upvotes: 2