title: Angular - Rendering a collection of child controls without a FormArray?
body: <p><strong>TL,DR;</strong></p>
  
  <p>When a collection of child controls is not a <a href="https://angular.io/api/forms/FormArray" rel="nofollow noreferrer">FormArray</a>, how can it be rendered?</p>
  
  <pre><code>// 'foo', 'bar' and 'baz' are actually names chosen by the user.
  // and are *not* known ahead-of-time.
  
  let form = this.fb.group({
      fields: this.fb.group({
        foo: this.fb.control(''),
        bar: this.fb.control(''),
        baz: this.fb.control('')
      })
  });
  </code></pre>
  
  <p>I'm using a <a href="https://angular.io/api/forms/FormGroup" rel="nofollow noreferrer">FormGroup</a> for <code>fields</code> because the <code>JSON</code> representation resulting from the <a href="https://angular.io/api/forms/AbstractControl#value" rel="nofollow noreferrer">value</a> property must be an <code>object</code> and not an <code>array</code>.</p>
  
  <p>How can <code>fields</code> be rendered without <code>*ngFor</code> - since <code>fields</code> is not iterable, it will not work.</p>
  
  <hr>
  
  <p><strong>Detail;</strong></p>
  
  <p>I want to render a collection of child controls belonging to an <a href="https://angular.io/api/forms/Form" rel="nofollow noreferrer">Angular Form</a>, but <em>not</em> in a <a href="https://angular.io/api/forms/FormArray" rel="nofollow noreferrer">FormArray</a>.</p>
  
  <pre><code>// Use FromBuilder to create the form.
  constructor(private readonly fb: FormBuilder) { }
  </code></pre>
  
  <p>The form must represent a structure consisting of <code>fields</code> which contain key/value pairs:</p>
  
  <pre><code>// Create the form with no/empty fields to start.
  let form = this.fb.group({
      fields: this.fb.group({})
  });
  </code></pre>
  
  <p>I don't know how many child controls will exist in <code>fields</code> - they will be added from a user action.</p>
  
  <p>At this point, it's common for <code>fields</code> to be a <a href="https://angular.io/api/forms/FormArray" rel="nofollow noreferrer">FormArray</a>, but I must use a <a href="https://angular.io/api/forms/FormGroup" rel="nofollow noreferrer">FormGroup</a> because the representation resulting from the Form <a href="https://angular.io/api/forms/AbstractControl#value" rel="nofollow noreferrer">value</a> must be a JSON <code>object</code> and not a JSON <code>array</code>.</p>
  
  <p>At some point after the app has loaded, child controls are added to <code>fields</code> using <a href="https://angular.io/api/forms/FormGroup#addControl" rel="nofollow noreferrer">addControl</a>. Control names are actually <strong>chosen by the user</strong>. </p>
  
  <p>For simplicity I have hard-coded them here as <code>foo</code>, <code>bar</code> and <code>baz</code>:</p>
  
  <pre><code>const fields = form.get('fields');
  
  const foo = new FormControl('');
  fields.addControl('foo', foo);
  
  const bar = new FormControl('');
  fields.addControl('bar', bar);
  
  ...
  
  const baz = new FormControl('');
  fields.addControl('baz', baz);
  </code></pre>
  
  <p>Ideally I would used <code>*ngFor</code>, but since <code>controls</code> is not iterable, this will not work:</p>
  
  <pre><code>&lt;ng-container [formGroup]="form"&gt;
  
    &lt;ng-container formGroupName="fields"&gt;
  
         &lt;mat-form-field *ngFor="let f of form.get('fields').controls"&gt;
  
           &lt;input matInput ...&gt;
  
         &lt;/mat-form-field&gt;
  
    &lt;/ng-container&gt;
  
  &lt;/ng-container&gt;
  </code></pre>
  
  <p>Additionally, I don't know the name of any child controls within <code>fields</code> - since as mentioned earlier, the name's of newly added controls are actually chosen by the user.</p>