I am trying to learn about Angular2's reactive forms by making a contact form. It all works good but there's an error that seems to give me quite some trouble. Everything works just fine when I use Validators.required
but as soon as I add Validators.minLength
or anything else on one of the controls everything messes up and I get this error in the browser's console: Expected validator to return Promise or Observable.
. I looked around but I couldn't really find a simple explanation/ Here's my component:
export class ContactRouteComponent {
contactForm: FormGroup;
reasons = REASONS;
constructor(private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.contactForm = this.fb.group({
name: ['', <any>Validators.required, <any>Validators.minLength(3)],
email: ['', <any>Validators.required],
reason: ['',<any>Validators.required],
message: ['', <any>Validators.required]
});
// AFISEAZA MESAJE EROARE
this.contactForm.valueChanges.subscribe(data => this.onValueChanged(data));
this.onValueChanged();
}
onSubmit() {
console.log(this.prepareContactForm());
this.contactForm.reset();
}
prepareContactForm() {
const formModel = this.contactForm.value;
const contactValues: Contact = {
name: formModel.name as string,
email: formModel.email as string,
reason: formModel.reason as string,
message: formModel.message as string
};
return contactValues;
}
onValueChanged(data?: any) {
if(!this.contactForm) { return; }
const form = this.contactForm;
for(const field in this.formErrors) {
// clear previous messages
this.formErrors[field] = '';
const control = form.get(field);
if(control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for(const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'name': '',
'email': '',
'reason': '',
'message': ''
}
validationMessages = {
'name': {
'required': 'Name is required',
'minLength': 'Name has to be...'
},
'email': {
'required': 'Name is required'
},
'reason': {
'required': 'Name is required'
},
'message': {
'required': 'Name is required'
}
}
}
When you have multiple validation rules, you must insert them inside of an array as such:
this.fb.group({
password: ['', [ Validators.required, Validators.minLength(5)] ]
})
Update to Angular v5
A more recent implementation without FormBuilder
:
form = new FormGroup({
email: new FormControl('',
Validators.compose([ Validators.minLength(5), Validators.email ])),
});
When you add more than one validator in the form builder, you should use an array []
braces for the validators
this.contactForm = this.fb.group({
name: ['',
[Validators.required, Validators.minLength(3)]
],
email: ['', Validators.required],
reason: ['', Validators.required],
message: ['', Validators.required]
});