title: FormArray in dynamic form angular
body: <p>I have implemented a stackblitz where you can create a dynamic form using some configuration. Everything works fine till you use a <code>FormArray</code>. What's the idea? Basically you can have many fields in your configuration file with different type. For example <code>checkbox</code>, <code>text</code>, <code>number</code> <code>select</code> etc. In some case you should have a more complex structure and so you should have a <code>FormArray</code>. In this stackblitz I tried to represent what's going on</p>
  <p><a href="https://stackblitz.com/edit/angular-dynamic-form-builder-gycshd?file=app/dynamic-form-builder/dynamic-form-builder.component.ts" rel="nofollow noreferrer">https://stackblitz.com/edit/angular-dynamic-form-builder-gycshd?file=app/dynamic-form-builder/dynamic-form-builder.component.ts</a></p>
  <p>So, when I found an <code>array</code> type I'm going to create a FormArray instead of a simple <code>FormControl</code> that's my list of fields</p>
  <pre><code> public fields: any[] = [
      {
        type: &quot;text&quot;,
        name: &quot;firstName&quot;,
        label: &quot;First Name&quot;,
        required: true
      },
      {
        type: &quot;text&quot;,
        name: &quot;lastName&quot;,
        label: &quot;Last Name&quot;,
        required: true
      },
      {
        type: &quot;text&quot;,
        name: &quot;email&quot;,
        label: &quot;Email&quot;,
        required: true
      },
      {
        type: &quot;text&quot;,
        name: &quot;description&quot;,
        label: &quot;Description&quot;,
        required: true,
        multiLine: true
      },
      {
        type: &quot;dropdown&quot;,
        name: &quot;country&quot;,
        label: &quot;Country&quot;,
        value: &quot;in&quot;,
        required: true,
        options: [{ value: &quot;in&quot;, label: &quot;India&quot; }, { value: &quot;us&quot;, label: &quot;USA&quot; }]
      },
      {
        type: &quot;array&quot;,
        name: &quot;users&quot;,
        label: &quot;Users&quot;,
        structure: &quot;users.json&quot;
      }
    ];
  </code></pre>
  <p>And here's my dynamic form builder component</p>
  <pre><code>export class DynamicFormBuilderComponent implements OnInit {
    @Output() onSubmit = new EventEmitter();
    @Input() fields: any[] = [];
    form: FormGroup;
    allDatas: any;
    constructor() {}
  
    ngOnInit() {
      let fieldsCtrls = {};
      this.allDatas = getData();
      for (let f of this.fields) {
        if (f.type != &quot;array&quot;) {
          fieldsCtrls[f.name] = new FormControl(
            this.allDatas[f.name] || &quot;&quot;,
            Validators.required
          );
        } else {
          fieldsCtrls[f.name] = new FormArray([
            new FormControl(this.allDatas[f.name] || &quot;&quot;, Validators.required)
          ]);
        }
      }
      this.form = new FormGroup(fieldsCtrls);
    }
  }
  </code></pre>
  <p>As you can see, I set a value from allDatas, if exists, and I create the FormGroup with FormControls and FormArray. But when I generate the <code>arraybox</code> I have errors. This is the arraybox component that displays a FormArray control:</p>
  <pre><code>import { HttpClient } from &quot;@angular/common/http&quot;;
  import { Component, Input, OnInit } from &quot;@angular/core&quot;;
  import { FormGroup } from &quot;@angular/forms&quot;;
  import { ConfigService } from &quot;../../config.service&quot;;
  
  @Component({
    selector: &quot;arraybox&quot;,
    template: `
      &lt;div [formGroup]=&quot;form&quot;&gt;
        &lt;div formArrayName=&quot;{{ field.name }}&quot;&gt;
          &lt;div
            *ngFor=&quot;let obj of arrayFileds; index as idx&quot;
            [formGroupName]=&quot;idx&quot;
          &gt;
            &lt;input
              attr.type=&quot;{{ obj.type }}&quot;
              class=&quot;form-control&quot;
              placeholder=&quot;{{ obj.name }}&quot;
              id=&quot;{{ obj.name }}&quot;
              name=&quot;{{ obj.name }}&quot;
              formControlName=&quot;{{ idx }}&quot;
            /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    `
  })
  export class ArrayBoxComponent implements OnInit {
    @Input() field: any = {};
    @Input() form: FormGroup;
    arrayFileds: any = [];
  
    get isValid() {
      return this.form.controls[this.field.name].valid;
    }
    get isDirty() {
      return this.form.controls[this.field.name].dirty;
    }
  
    constructor(private config: ConfigService) {}
  
    ngOnInit(): void {
      this.arrayFileds = this.config.getData(this.field.structure);
      console.log(this.arrayFileds);
    }
  }
  </code></pre>
  <p>getData() returns the structure of that FormArray. In this case</p>
  <pre><code>[{
      &quot;label&quot;: &quot;Username&quot;,
      &quot;name&quot;: &quot;userName&quot;,
      &quot;type&quot;: &quot;text&quot;
  }, {
      &quot;label&quot;: &quot;User email&quot;,
      &quot;name&quot;: &quot;userEmail&quot;,
      &quot;type&quot;: &quot;text&quot;
  }]
  </code></pre>
  <p>The errors in console are:</p>
  <pre><code>ERROR
  Error: Cannot find control with path: 'users -&gt; 0 -&gt; 0'
  ERROR
  Error: Cannot find control with path: 'users -&gt; 1'
  </code></pre>
  <p>I really don't know what's wrong here. How can I use FormArray to show the fields with their values in this form?</p>
  <p>NB. stackblitz gets me an error if I use http to parse json so for now I'm using directly an import of the json. Basically, <code>this.field.structure</code> in this example is not used (but it should be).</p>