'How can I cast an AbstractControl to a FormControl in a template?
I have a FormGroup that I'm passing from a parent component to a child, and then within that FormGroup there's a control that I'm passing from the first child to a second child. However I then want to use the control in a button so that I can alter the state of the formgroup using it.
However when I do form.get('controlName'), it returns an AbstractControl, and when I try to pass the AbstractControl to the [formControl]
directive of the button I get an error saying that Type AbstractControl is not assignable to abstract control
.
Usually I'd just cast the control to a FormControl in my component but this won't work as I'm using the control directly in the template.
The form
this.form = this._formBuilder.group({
cost: this._formBuilder.control(''),
width: this._formBuilder.control('')
})
First child template
<app-form-subsection-cost [subsectionFormControl]="form.get('cost')"></app-form-subsection-cost>
Second child
export class FormSubsectionCostComponent implements OnInit {
@Input() subsectionFormControl: AbstractControl;
constructor() { }
ngOnInit(): void {
}
}
Second child template
<button [formControl]="subsectionFormControl as FormControl" value="Yes">Yes</button> //Error on formControl directive
I can't do this:
<app-form-subsection-cost [subsectionFormControl]="form.get('cost')"
[subsectionFormControl]="form.get('cost') as FormControl"></app-form-subsection-cost>
Solution 1:[1]
What I do is define a method in my component to return the FormControl with a given name.
fc(name) { return this.form.get(name) as FormControl; }
Then use it in the template:
[formControl]="fc('subsectionFormControl')
Solution 2:[2]
You can write a method like Thor suggested, but unfortunately the best supported out-of-the-box solution I have found is to use the $any() cast function. This is less safe, but you don't have to add a cast function to every affected component.
Solution 3:[3]
For what it's worth: define setter / getter, and allow superclass on setter:
@Input()
set control(control: AbstractControl) {
this._control = control as FormControl;
}
get control(): FormControl {
return this._control;
}
If there's a chance the cast in the setter will backfire, do a typeof + throw Error beforehand to fail-fast.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Thor |
Solution 2 | Coderer |
Solution 3 | Simon |