Search code examples
javascriptangularangular-reactive-formsangular-formsangular-formbuilder

Angular Reactive forms formgroup


I need to have a formControl for two different arrays under the same node so I could add and delete a respective nested node in the given Reactive form.

Expected JSON Format:

{
  "title": null,
  "days": [
    {
      "date": null,
      "nodes": [
        {
          "type": "leg",
          "from": null,
          "to": null
        },
        {
          "type": "activity",
          "category": null
        }
      ]
    }
  ]
}

I have implemented control on day and node for which I was able to add and delete the form fields respectively however I need separate controls for type leg and activity under nodes.

Is there any way to implement nested formControl in here?

Update: Need two formgroups under a form array, please help to implement in HTML.

initX() {
    return this.fb.group({
      'date': [],
      'nodes': this.fb.array([
        this.initY(),
        this.initZ()
      ]),
    });
  }

  initY() {
    return this.fb.group({
      'type': ['leg'],
      'from': [],
      'to': []
    })
  }

  initZ() {
    return this.fb.group({
      'type': ['activity'],
      'category':[],
      'cost':[]
    })
  }

Error: Cannot find control with path: 'days -> 0 -> nodes -> 1 -> from'

Can find the stackblitz of the sample code here: https://stackblitz.com/edit/angular-ivy-fkgxrr


Solution

  • well, in my another answer, the "nodes" array is like

    [
     {"type": "leg","from": null,"to": null,"category": null}
     {"type": "leg","from": null,"to": null,"category": null}
    ]
    

    A formArray need has all his elements with the sames properties

    Question: nodes is only an array with two elements (one for control Leg and another one for control category)?

    In this case days is a formArray, each element is a formGroup with two peoperies, one of them is an array (not a formArray) with two elements

    form=new FormGroup({
      title:new FormControl()
      days:new FormArray([
         date:new FormControl(),
         nodes:[new FormGroup({...}),new FormGroup({..})]
      ])
    })
    

    in this case you can has three getter

    get days():FormArray
    {
        return this.formGroup.get('days') as FormArray;
    }
    get leg(index)
    {
        return this.days.at(i).get('nodes')[0] as FormGroup
    }
    get category(index)
    {
        return this.days.at(i).get('nodes')[1] as FormGroup
    }
    

    And use directly [formGroup] in a div, e.g.

    <div [formGroup]="category[i]">
       <input formControlName="from">
       ...
    </div>
    

    else I can not understand your json