Using a FormArray instead of FormControl Angular

I would like to use FormArray instead of FormControl for the following typescript code

import { Component, OnInit, Input } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms';
import { WebsocketService } from '../../core/websocket.service';
import { AppEngineMessage } from '../../core/models/app-engine-message';
@Component({
  selector: 'app-auxilary',
  templateUrl: './auxilary.component.html',
  styleUrls: ['./auxilary.component.css']
})
export class AuxilaryComponent implements OnInit {

  private appEngineMsg: AppEngineMessage;
  public auxConfigform: FormGroup;
  @Input() m_bReadOnly: boolean;
  constructor(private fb: FormBuilder, private wsService: WebsocketService) { }

  // ---------INTIALISING VALUES BASED ON VALUES FROM WEBSOCKET-------------------------------
  ngOnInit() {
    // ------------------------FORM CONTROL IS DECLARED FOR DESCRIPTION-------------------
    // this.auxConfigform = this.fb.group({
    //   desc : this.fb.array([8]),
    //   temp : this.fb.array([4]),
    //   switch : this.fb.array([4]),
    //   space : this.fb.array([4])
    // });

    this.auxConfigform = new FormGroup({
      desc0: new FormControl(),
      desc1: new FormControl(),
      desc2: new FormControl(),
      desc3: new FormControl(),
      desc4: new FormControl(),
      desc5: new FormControl(),
      desc6: new FormControl(),
      desc7: new FormControl(),

      //-------------------------FORM CONTROL IS DECLARED FOR TEMPSENSOR--------------------
      temp0: new FormControl(),
      temp1: new FormControl(),
      temp2: new FormControl(),
      temp3: new FormControl(),
      //-------------------------FORM CONTROL IS DECLARED FOR Switch radio button--------------------
      switch4: new FormControl(), 
      switch5: new FormControl(),
      switch6: new FormControl(),
      switch7: new FormControl(),
      //-----------------------FORMCONTROL IS DECLARED FOR SPACE SENSOR Radio button--------------------
      space0: new FormControl(),
      space1: new FormControl(),
      space2: new FormControl(),
      space3: new FormControl(),
    });

    this.wsService.appEngineMsg.subscribe(appMsg => {
      if (Object.keys(appMsg).length != 0) {
        this.appEngineMsg = appMsg;

        //-----------This is used to intialise Decription text Box-----------------------------------
        for (let i=0; i<8; i++)
          this.auxConfigform.controls['desc'+i].patchValue(this.appEngineMsg.AUX[i].Description);
        for (let i=0; i<4; i++)
          this.auxConfigform.controls['temp'+i].patchValue(String(this.appEngineMsg.AUX[i].TempSensor));
        for (let i=4; i<8; i++)
          this.auxConfigform.controls['switch'+i].patchValue(String(this.appEngineMsg.AUX[i].TempSensor));
        for (let i=0; i<4; i++)
          this.auxConfigform.controls['space'+i].patchValue(this.appEngineMsg.AUX[i].SpaceAvg);
      }
      else {
        for (let i=0; i<4; i++)
          this.auxConfigform.controls['temp'+i].patchValue('false');
        for (let i=4; i<8; i++)
          this.auxConfigform.controls['switch'+i].patchValue('false');
        }
    });
    if (this.m_bReadOnly)
      this.auxConfigform.disable();
  }
}

but I do not know the correct syntax for object indexing in the template URL

<form [formGroup]="auxConfigform" (ngSubmit)="onFinish()">
  <div>
    <label for="" class="w60">AUX 1</label>
    <input matInput matKeyboard type="text" name="desc0" placeholder="" class="txt-fld-200" formControlName="desc0"
      maxlength="50">

    <input type="radio" id="test2" name="temp0" value='false' formControlName="temp0">
    <label for="test2" class="w140">Switch</label>
    <input type="radio" id="test1" name="temp0" value='true' formControlName="temp0">
    <label for="test1" class="pr-40" *ngIf="m_bReadOnly==false">Temp Sensor</label>
    <input type="checkbox" id="check" name="radio-group1" formControlName="space0"
      *ngIf="m_bReadOnly==false && auxConfigform.get('temp0').value=='true'">
    <label for="check" *ngIf="m_bReadOnly==false && auxConfigform.get('temp0').value=='true'">Space Sensor </label>
  </div>
  <div>
    <label for="" class="w60">AUX 2</label>
    <input matInput matKeyboard type="text" name="desc1" placeholder="" class="txt-fld-200" formControlName="desc1"
      maxlength="50">
    <input type="radio" id="test5" name="temp1" value='false' formControlName="temp1">
    <label for="test5" class="w140">Switch</label>
    <input type="radio" id="test4" name="temp1" value='true' formControlName="temp1">
    <label for="test4" class="pr-40" *ngIf="m_bReadOnly==false">Temp Sensor</label>
    <input type="checkbox" id="check2" name="radio-group2" class="checkstyle" formControlName="space1"
      *ngIf="m_bReadOnly==false && auxConfigform.get('temp1').value=='true'">
    <label for="check2" *ngIf="m_bReadOnly==false && auxConfigform.get('temp1').value=='true'">Space Sensor </label>
  </div>
</form>

I have the other question, how to automatic generate my GUI base on the JSON array in ngOnInit function? For example, my this.appEngineMsg.AUX is as below:

 [{
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    },
    {
        "Description": "",
        "TempSensor": true,
        "SpaceAvg": false,
        "SwitchStatus": false
    }
]

enter image description here

If I add or remove an element in JSON array, the GUI will be updated correspondingly

1 answer

  • answered 2019-10-15 17:50 Chellappan

    Since you have array of Object, create FormGroup with individual form control property then use Validators to add Validation to reactiveform instead of adding html attribute on template.

    component.ts

     const arryOfAuxGroup = this.AUX.map(item => {
          return this.createauxGroup(
            item.Description,
            item.TempSensor,
            item.SpaceAvg,
            item.SwitchStatus
          );
        });
    this.auxConfigform = this.fb.group({
          aux: this.fb.array(arryOfAuxGroup)
    });
    createauxGroup(description, tempSensor, spaceAvg, switchStatus) {
        return this.fb.group({
          description: [description, Validators.maxLength(50)],
          tempSensor: [tempSensor],
          spaceAvg: [spaceAvg],
          switchStatus: [switchStatus]
        });
      }
    

    Example