Get access to FormControl from the custom form component in Angular


Get access to FormControl from the custom form component in Angular



I have a custom form control component in my Angular application, which implements ControlValueAccessor interface.


ControlValueAccessor



However, I want to access the FormControl instance, associated with my component. I'm using reactive forms with FormBuilder and providing form control using formControlName attribute.


FormControl


FormBuilder


formControlName



SO, how do I access FormControl instance from inside of my custom form component?


FormControl




3 Answers
3



This solution was born from the discussion in the Angular repository. Please, make sure to read it or even better to participate if you are interested in this problem.



I've studied the code of FormControlName directive and it's inspired me to write the following solution:


FormControlName


@Component({
selector: 'my-custom-form-component',
templateUrl: './custom-form-component.html',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: CustomFormComponent,
multi: true
}]
})
export class CustomFormComponent implements ControlValueAccessor, OnInit {

@Input() formControlName: string;

private control: AbstractControl;


constructor (
@Optional() @Host() @SkipSelf()
private controlContainer: ControlContainer
) {
}


ngOnInit () {

if (this.controlContainer) {
if (this.formControlName) {
this.control = this.controlContainer.control.get(this.formControlName);
} else {
console.warn('Missing FormControlName directive from host element of the component');
}
} else {
console.warn('Can't find parent FormGroup directive');
}

}

}



I'm injecting the parent FormGroup to the component and then getting the specific FormControl from it using control name obtained through formControlName binding.


FormGroup


FormControl


formControlName



However, be advised, that this solution is tailored specifically for the use case where FormControlName directive is used on host element. It won't work in other cases. For this you will need to add some additional logic. If you think, that this should be addressed by Angular, make sure to visit the discussion.


FormControlName





from where do you have this.control ?
– DAG
Dec 12 '17 at 16:54


this.control





@DAG as I stated in the answer: I'm injecting the parent FormGroup to the component and then getting the specific FormControl from it using control name obtained through formControlName binding.
– Slava Fomin II
Dec 13 '17 at 6:32


I'm injecting the parent FormGroup to the component and then getting the specific FormControl from it using control name obtained through formControlName binding.





@SlavaFominII: Instead of injecting parent form group and then accessing the control using formControllerName input binding, can't we just pass the form control as the input binding? I had a similar requirement where I wanted to access the form control from custom form component and I passed that form control as an input binding to custom form component.
– Ritesh
Jan 3 at 7:21



As @Ritesh has already written in the comment you can pass form control as an input binding:


<my-custom-form-component [control]="myForm.get('myField')" formControlName="myField">
</my-custom-form-component>



And then you can get form control instance inside your custom form component like this:


@Input() control: FormControl;



Using formControlName as an input parameter doesn't work when binding via the [formControl] directive.


formControlName


[formControl]



Here is a solution that works both ways without any input parameters.




export class MyComponent implements AfterViewInit {

private control: FormControl;

constructor(
private injector: Injector,
) { }

// The form control is only set after initialization
ngAfterViewInit(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
this.control = ngControl.control as FormControl;
} else {
// Component is missing form control binding
}
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to add background colour in existing image using Swift?

Moria Casán

How to make file upload 'Required' in Contact Form 7?