Wolf359
Wolf359

Reputation: 2725

Angular 10 strict mode: AbstractControl vs FormControl

I have this custom component :

<my-component [control]="..."></my-component>

Here, control is defined as :

@Input() control: FormControl;

Usage of my-component :

this.myFormGroup = new FormGroup({
    name: new FormControl('')
});

<my-component [control]="myFormGroup.controls.name"></my-component>

The Error:

Angular 10 strict mode complains about "myFormGroup.controls.name" not being a FormControl.

"controls" is defined in FormGroup as an object where every field is of type AbstractControl :

// forms.d.ts
export declare class FormGroup extends AbstractControl {
    controls: {
        [key: string]: AbstractControl;
    };
    // ....
}

This code would work at runtime but doesn't compile.

What would be the best way to solve this?

Upvotes: 7

Views: 4962

Answers (4)

dibfibo
dibfibo

Reputation: 21

Now you use angular type form. Example

U have object interface for a book.

interface Book { id: number name: string author: string }

U want create a form to edit name and author properties.

Define a type type Form = FormGroup<Partial<{[K in keyof Book]:FormControl}>>

Declare a form public form : Form

Try!

Upvotes: 0

Eliseo
Eliseo

Reputation: 57981

Another aproach is use a setter in input. In your component(*)

  control:FormControl //declare a variable
  @Input('control') set _control(value:AbstractControl) //<--here expect an AbstracControl
  {
    this.control=value as FormControl
  }

A fool example in stackblitz

(*) I choose the way @Input('control') set anyfunctionName to not change your component

Upvotes: 2

Alexander Staroselsky
Alexander Staroselsky

Reputation: 38827

You can use AbstractControl method get() to access a control in combination with a TypeScript class get function:

get name() {
  return this.myFormGroup.get('name') as FormControl
}

You can then access the control easily in templates:

<div>{name.value} {name.valid}</div>

This is described in the documentation on Reactive Forms

Hopefully that helps!

Upvotes: 1

Michael
Michael

Reputation: 2454

I've avoided this in the past by keeping a reference to the form control outside of the form group.

Eg:

this.nameControl = new FormControl()
this.myFormGroup = new FormGroup({
    name: this.nameControl,
});

Upvotes: 2

Related Questions