angularformsangular-formbuildermat-tab

Create many forms in one component


I'm trying to create many forms in one component. I've tried to implement this with mat-tab-groups

<mat-tab-group>
  <mat-tab label="form1">
    <form>...</form>
  </mat-tab>
  <mat-tab label="form2">
    <form>...</form>
  </mat-tab>
</mat-tab-group>

I have these functions that create the forms in the ts:

createForm1(){
  this.form = this.formBuilder.group({
    field1: [''],
    field2: [''],
    ...
  })
}
createForm2(){
  this.form = this.formBuilder.group({
    field1: [''],
    field2: [''],
    ...
  })
}

I've called this functions in the constructor:

constructor(some dependencies){
  this.createForm1;
  this.createForm2;
}

However, when the createForm2() is called, it crashes. If I change the order, the form2 is created and form1 crashes. The error is ERROR Error: Cannot find control with name: someField.

I'm guessing the error is related to the tabs (only able to create the form of active tabs), but I don't know how to solve it.

Further Info

In the html, the controls are accessed via:

<div class="form-group"><input type="number" formControlName="field1" class="form-control"/></div>
<div class="form-group"><input type="number" formControlName="field2" class="form-control"/></div>

Solution

  • I think you are missing a couple of things.

    I created a stackblitz with the details given above and they work. https://stackblitz.com/edit/angular-4y6edt

    You should also give the <form> the [formGroup] to tell it to it bind to the relevant form group.

     <form [formGroup]="form1">
          <div class="form-group">
            <input type="number" formControlName="field1" class="form-control" />
          </div>
          <div class="form-group">
            <input type="number" formControlName="field2" class="form-control" />
          </div>
        </form>
      </mat-tab>
      <mat-tab label="form2">
        <form [formGroup]="form2">
          <div class="form-group">
            <input type="number" formControlName="field1" class="form-control" />
          </div>
          <div class="form-group">
            <input type="number" formControlName="field2" class="form-control" />
          </div>
        </form>
    

    In your .ts component, you are initializing the same component twice:

    createForm1(){
      this.form = this.formBuilder.group({
        field1: [''],
        field2: [''],
        ...
      })
    }
    createForm2(){
      this.form = this.formBuilder.group({
        field1: [''],
        field2: [''],
        ...
      })
    }
    

    You should have two different formGroups i.e. form1 and form2, like this:

     createForm1() {
        this.form1 = this.formBuilder.group({
          field1: [''],
          field2: [''],
        });
      }
      createForm2() {
        this.form2 = this.formBuilder.group({
          field1: [''],
          field2: [''],
        });
      }
    

    And finally call them in your constructor like this:

     constructor(private formBuilder: FormBuilder) {
        this.createForm1();
        this.createForm2();
      }