Inside one of my custom form controls I need to access its formcontrol. It turns out that this is not very straight forward. On the internet I found 3 solutions:
Use the validator interface and access the control as followsd
public validate(c: FormControl) {
if (!this.control)
this.control=c;
return c?.errors;
}
Use inject
or the Injector
which (in my case) always give a Circular dependency injection error or No provider for NgControl
this.ngControl = inject(NgControl);
or
this.ngControl = this.injector.get(NgControl);
Access the FormControl using @Input
@Input() formControl: FormControl;
This one doesn't work with formControlName
unfortunately.
So the question is, based on my findings, that I should use 1) or 3). Or is there an other solution?
As I wrote you can get it from FormControlName
directive applied to your host element.
Keep in mind that this is a circular dependency injection therfore you have to access it in post constuction phase - in my example, it is ngAfterViewInit
callback
In your custom form control
constructor(@Optional() @Host() private injector: Injector) {
}
ngAfterViewInit() {
// setTimeout(() => {
const formControlName = this.injector.get(FormControlName);
console.log('ctrl??', formControlName.control);
//
});
}
which results in
ctrl?? FormControl{validator: ƒ, asyncValidator: null, _onCollectionChange: ƒ, pristine: true, …}
I have forked some random stackblitz example to POC it out.
Ignore errors as those are for other 2 controls that uses ngModel
and `formControl instead
on the other hand, this is actually the same what you have already tried, it just bypassing circular dependency injection problem thus you can adopt your solution the same way