Home > Software design >  Two way binding FormGroup into child component containing a nesting form
Two way binding FormGroup into child component containing a nesting form

Time:12-08

The introduction

Hi, in my internship, I am supposed to create a stepper form with a custom BillingComponent embedded into the form. The Billing itself is a pretty straightforward form with formGroup:

code simplified for clarity reasons

<div  id="billing">
  <form [formGroup]="formGroup">
    <h4>Billing Information</h4>
    <table>
      <tr>
        <td>Tax Identification</td>
        <td><input formControlName="tax" name="tax" type="text"></td>
        <td></td>
      </tr>
    </table>
  </form>
</div>

and here is the component code

@Component({
  selector: 'app-billing',
  templateUrl: './billing.component.html',
  styleUrls: ['./billing.component.scss']
})
export class BillingComponent implements OnInit {
  @Input() submitted: boolean; // this is my last resort, to use boolean update to "fire" the event emmiter
  @Input() advertiser: Advertiser | Billing = new Billing(); // object with data
  @Input() account: Account = new Account(); // another data object 
  @Output() formGroupEventEmitter = new EventEmitter<FormGroup>(); //
  @Input() formGroup: FormGroup = this.getChecks();


  constructor(private formBuilder: FormBuilder) {
  }

  getChecks(): FormGroup {
    return this.formBuilder.group(
      {
        tax: [this.advertiser.adv_tax_localization, Validators.required],
        // more validator fields here
      }
    );
  }

   ngOnInit(): void {

}


The problem

The problem itself occurs when I get data from this form using parent. My first thought was to use NgModel with the banana syntax, but that didn't work, throwing errors all over the page. So this is how the app-billing component is incorporated into the main stepper form:

<cdk-step> <!-- step for the CdkStepperForm -->
  <div>
    <form [formGroup]=termsGroup>
      <input type="text" formControlName="testControl">
      <app-billing [advertiser]="advertiser" [account]="account"></app-billing>
      <div id="declaration">
        <table >
          <tr>
            <td>Legality declaration</td>
            <td>
              <input type="checkbox" formControlName="legality">
            </td>
          </tr>
          <tr>
            <td>Notice of bankruptcy</td>
            <td>
              <input type="checkbox" formControlName="bankruptcy">
            </td>
          </tr>
        </table>
        <div >
          <button >BACK</button>
          <button  (click)="register()">REGISTER</button>
        </div>
      </div>
    </form>
  </div>
</cdk-step>

So far, I've tried to use NgModel, even tried to two-way-bind a FormGroup into the app-billing component, though it only worked one way.

TLDR: I have problems extracting data from app-billing with two-way binding, and ngModel is not working; plus, I heard its usage with Reactive forms would be deprecated soon.

CodePudding user response:

You can use ViewChild to get the reference of BillingComponent and used it get access to the component.

// parent component
@ViewChild(BillingComponent) billing!: BillingComponent

register() {
  const billing = this.billing.formGroup.value
}

CodePudding user response:

Apparently ControlContainer is the thing I was searching for! Found a pretty well written repository on github regarding this:

https://github.com/pstarostka-zz/nested-forms

  • Related