4

I have form with form controls in component A. I've decided to move some form controls to separate component B in order to prevent code duplicates in other components.

A.html:

<form [formGroup]="editForm">
  <B [formControllerName]="'name'" ></B>
  <!-- Other form controls -->
</form>

B.html:

<select class="form-select" formControlName="{{formControllerName}}">
  <!-- Options -->
</select>

I got this error: Error: NG01050: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).

How I can get access to form controller from component A?

6
  • for an individual control or full (sub) formgroup I recommend control value accessor. Recommend looking at Resources on a previous answer I've posted stackoverflow.com/a/57280011/4711754 Commented Aug 23, 2022 at 8:25
  • Move the FormGroup into a service, or create a wrapper component and make the FromGroup an input on A and B. Commented Aug 23, 2022 at 9:21
  • 1
    @AndrewAllen, In my "personal" opinion, a control value accessor should be used only when the component is "complex" (a datepicker, a credit card ask, a circular dial, and drag-drop component...): components that require more that simple group some inputs. Commented Aug 23, 2022 at 11:24
  • @MikkelChristensen, the two components are at time in the app, it's unnecesary use a service Commented Aug 23, 2022 at 11:25
  • @Eliseo you're probably right, I only use cva as you describe. I've tested using cva for sub formgroup and it went fine but not used in more complex situations Commented Aug 23, 2022 at 11:35

1 Answer 1

6

It's possible using viewProviders, see, e.g. this SO about FormArray

A more simple

@Component({
  selector: 'hello',
  template: `<h1>Hello </h1>
      <input [formControlName]="name"/>
  `,
  viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class HelloComponent  {
  @Input() name: string;
  
  constructor(){}
}

You can use

<form [formGroup]="form">
  <hello [name]="name" > </hello>
</form>

in .ts

  name = 'name';
  form=new FormGroup({
    name:new FormControl()
  })

See stackblitz

The another way is pass the own FormControl and use

   control:FormControl
   @Input('control') set _control(value){
       this.control=value as FormControl
   }

   <input [formControl]="control">

You use as

   <hello [control]="form.get('name')" > </hello>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.