Reputation: 129
I'm new to angular, and I'm learning reactive forms.
There's this one issue that I'm not able to solve. Here, I'm trying to create a reusable input component for my form. But, there's this Abstractform control error
that I'm not able to resolve.
NOTE: I don't wanna use "strictTemplates": false
.
Can someone help me understand what's exactly going on here and how can I resolve this error?
Here's the list of files to reproduce the error -
reactive-form.component.ts
import { Component } from '@angular/core'
import { FormGroup, FormControl, Validators } from '@angular/forms'
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html',
styleUrls: ['./reactive-form.component.css'],
})
export class ReactiveFormComponent {
cardForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.minLength(3)]),
})
}
reactive-form.component.html (Getting error here)
<form [formGroup]="cardForm"></form>
<!--Type 'AbstractControl' is missing the following properties from type 'FormControl': registerOnChange, registerOnDisabledChange, _applyFormState -->
<app-input [control]="cardForm.controls.name"></app-input>
input.component.ts
import { Component, Input } from '@angular/core'
import { FormControl } from '@angular/forms'
@Component({
selector: 'app-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.css'],
})
export class InputComponent {
@Input() control: FormControl = new FormControl()
}
input.component.html
<input [formControl]="control" />
<ng-container *ngIf="control.dirty && control.touched && control.errors">
<div *ngIf="control.errors.required">Value is required</div>
<div *ngIf="control.errors.minlength">
Value should be longer Required min value is
{{ control.errors.minlength.requiredLength }}
</div>
</ng-container>
NOTE: I've already analyzed a couple of similar threads but those are hard for me to understand. Will appreciate it if someone can take this example and explain what's wrong here.
Upvotes: 1
Views: 4002
Reputation: 57929
You can get another aproach that is use a getter in your compoment
control:FormControl=new FormControl();
@Input('control') set _(value)
{
this.control=value as FormControl;
}
Upvotes: 1
Reputation: 88
Your input component must be like this: ts file:
@Component({
selector: 'app-input',
templateUrl: './input.component.css.html',
styleUrls: ['./input.component.css.css'],
encapsulation: ViewEncapsulation.None,
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR] })
export class InputComponent implements ControlValueAccessor,OnChanges{
InputValue: any;
@Input() control: FormControl = new FormControl();
onChange(value) {
this.propagateChange(value);
}
writeValue(value: any) {
this.InputValue = value;
}
registerOnChange(fn: any)
{
this.propagateChange = fn;
}
registerOnTouched(fn: any) {
this.propagateTouched = fn;
}
propagateChange = (_: any) => { }
propagateTouched = (_: any) => { }
}
html file:
<input [(ngModel)]='InputValue' (ngModelChange)="onChange($event)" />
<ng-container *ngIf="control.dirty && control.touched && control.errors">
<div *ngIf="control.errors.required">Value is required</div>
<div *ngIf="control.errors.minlength">
Value should be longer Required min value is
{{ control.errors.minlength.requiredLength }}
</div>
</ng-container>
get name() {
return this.cardForm.get('name');
}
<app-input [control]="name" formControlName="name">
</app-input>
Upvotes: 0
Reputation: 51135
You get this error because Angular doesn't know that you are passing FormControl
. Instead, Angular treats it as AbstractControl
.
Type 'AbstractControl' is missing the following properties from type 'FormControl': registerOnChange, registerOnDisabledChange, _applyFormState
Add cardFormNameControl
getter to specify that you are passing FormControl
to InputComponent
.
reactive.component.html
export class ReactiveFormComponent {
...
get cardFormNameControl(): FormControl {
return this.cardForm.get('name') as FormControl;
}
}
<app-input [control]="cardFormNameControl"></app-input>
Upvotes: 4