How to structure or build form for the repetitive set of fields in angular 10?

<div class="card">
  <div>
    <span>Level </span>
  </div>
  <ul>
    <li>
      <div *ngFor="let sensorType of sensorsEnum">
        <mat-form-field class="col-12">
          <mat-label>Select {{ sensorType.name }}</mat-label>
          <mat-select formControlName="?">
            <mat-form-field appearance="outline" class="w-100">
              <input matInput #sensorTemperatureFilter />
            </mat-form-field>
            <mat-option *ngFor="
                      let sensor of sensors
                        | filter: sensorTemperatureFilter.value
                    " [value]="sensor.id">
              {{ sensor.id }}
            </mat-option>
          </mat-select>
        </mat-form-field>
      </div>
    </li>
  </ul>
</div>
export enum SensorsEnum {
  Temperature = "temperature",
  Humidity = "humidity",
  PH = "ph",
  EC = "ec",
  N = "N",
  P = "P",
  K = "K",
}

I am using the above enum to loop. The above html snippet produces one level. I need the same for 3 more levels side by side.

The level represents the depth of soil and for each level, different sensors should be selected. There are four levels 30,15,10,5. Each level has the same set of fields. Now I want to validate all these levels in one go when I click create. How do I structure the formGroup? Thanks in advance

Here this is a box with horizontal scroll with four different levels.

Answer

You can create a method that returns a form group containing the matching set of fields. You can then define a parent group that contains the four child groups built from this method.

Note: I’m using form builder which is imported as private fb:FormBuilder in the constructor.

public parentGroup = this.fb.group({
  level30: this.createGroup(data.level30),
  level15: this.createGroup(data.level15),
  level10: this.createGroup(data.level10),
  level5: this.createGroup(data.level5)
});

public createGroup = (data) => this.fb.group({
  tempurature: this.fb.control(data.tempurature.value),
  humidity: this.fb.control(data.humidity.value),
  ph: this.fb.control(data.ph.value),
  N: this.fb.control(data.N.value),
  P: this.fb.control(data.P.value),
  K: this.fb.control(data.K.value)
});

I’m taking a lot of liberty in guessing how your data is structured. Anyway, you now place the parent form group name in a wrapping DOM, and use formGroupName and formControlName for all child controls.

As long as the DOM control structure matches the above form group structure, you can get/validate data from the entire form using:

console.log(this.parentGroup.value);
/*
{
  level30: {
    tempurature: 15,
    humidity: 30,
    ph: 6.5,
    //...
  },
  level15: {
    //...
  },
  level10: {
    //...
  },
  level5: {
    //...
  }
}
*/