I have an Angular 2 application that uses the ReactiveForms
module to manage a form that uses a custom validator. The validator receives a FormControl
object. I have a few input fields that could use the same custom validator if only I knew the name of the field when the FormControl
was passed to the validator.
I can't find any method or public property on FormControl
that exposes the input field's name. It's simple enough to see its value, of course. The following shows how I would like to use it:
public asyncValidator(control: FormControl): {[key: string]: any} { var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece return new Promise(resolve => { this.myService.getValidation(theFieldName, control.value) .subscribe( data => { console.log('Validation success:', data); resolve(null); }, err => { console.log('Validation failure:', err); resolve(err._body); }); }); }
To fetch the value of a form control, we have to use value property on the instance of FormControl in our class. In the same way we can fetch the value in HTML template. city = new FormControl('Noida'); console. log(this.
The name corresponds to a key in the parent FormGroup or FormArray . Accepts a name as a string or a number. The name in the form of a string is useful for individual forms, while the numerical form allows for form controls to be bound to indices when iterating over controls in a FormArray . @Input('disabled')
You can use [(ngModel)] with Reactive forms. This will a completely different directive than the one that would be used without the formControlName . With reactive forms, it will be the FormControlNameDirective . Without the formControlName , the NgModel directive would be used.
To expand on Radim Köhler answer. here is a shorter way of writing that function.
getControlName(c: AbstractControl): string | null { const formGroup = c.parent.controls; return Object.keys(formGroup).find(name => c === formGroup[name]) || null; }
We can use .parent
property, well today ["_parent"]
(see more below):
export const getControlName = (control: ng.forms.AbstractControl) => { var controlName = null; var parent = control["_parent"]; // only such parent, which is FormGroup, has a dictionary // with control-names as a key and a form-control as a value if (parent instanceof ng.forms.FormGroup) { // now we will iterate those keys (i.e. names of controls) Object.keys(parent.controls).forEach((name) => { // and compare the passed control and // a child control of a parent - with provided name (we iterate them all) if (control === parent.controls[name]) { // both are same: control passed to Validator // and this child - are the same references controlName = name; } }); } // we either found a name or simply return null return controlName; }
and now we are ready to adjust our validator definition
public asyncValidator(control: FormControl): {[key: string]: any} { //var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece var theFieldName = getControlName(control); ...
.parent
later, ["_parent"]
nowAt the moment (today, now), current release is :
2.1.2 (2016-10-27)
But following this issue: feat(forms): make 'parent' a public property of 'AbstractControl'
And as already stated here
2.2.0-beta.0 (2016-10-20)
Features
- forms: make 'parent' a public property of 'AbstractControl' (#11855) (445e592)
- ...
we could later change the ["_parent"]
into .parent
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