Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get name of input field from Angular2 FormControl object?

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);           });     });   } 
like image 557
Michael Oryl Avatar asked Nov 01 '16 14:11

Michael Oryl


People also ask

How do you access value from FormControl?

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.

What is FormControl name?

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')

Can we use ngModel with Reactive forms?

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.


2 Answers

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; } 
like image 95
Chris Avatar answered Sep 20 '22 20:09

Chris


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"] now

At 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

like image 42
Radim Köhler Avatar answered Sep 20 '22 20:09

Radim Köhler