title: Angular Reactive Forms
body: <p>I have two Angular components.  One is called web-services and another is called web-service.  I am hosting a web-service on the template page of web-services and attempting to bind to its service property via the @Input() decorator that I am importing from @angular/core.  However, whenever a web service is selected, I'm getting an error message of 'Cannot read property controls of undefined' which seems to be a problem with my web-service.component.html when it accesses inputParameters.controls.  I've printed inputParameters.controls to the console after it's been set and both name and type are definitely there as form controls.  Am I accessing them incorrectly some how in the HTML?</p>
  
  <p>web-services.component.ts</p>
  
  <pre><code>export class WebServicesComponent implements OnInit {
    services: Observable&lt;WebService[]&gt;;
    isLoading = false;
    selectedService: WebService;
  
    constructor(private webServicesService: WebServicesService) { }
  
    ngOnInit() {
      this.getServices();
    }
  
    getServices() {
      this.isLoading = true;
      this.services = this.webServicesService.getWebServices()
        .finally(() =&gt; this.isLoading = false);
      this.selectedService = undefined;
    }
  
    selected(service: WebService) {
      this.selectedService = service;
    }
  
  }
  </code></pre>
  
  <p>web-services.component.html</p>
  
  <pre><code>&lt;h3 *ngIf="isLoading"&gt;&lt;i&gt;Loading services ... &lt;/i&gt;&lt;/h3&gt;
  &lt;h3 *ngIf="!isLoading &amp;&amp; !selectedService"&gt;Select a service:&lt;/h3&gt;
  
  &lt;ul class="ms-List" *ngIf="!selectedService"&gt;
      &lt;li class="ms-ListItem" tabindex="0" *ngFor="let service of services | async"&gt;
          &lt;span class="ms-ListItem-primaryText"&gt;{{service.name}}&lt;/span&gt; 
          &lt;span class="ms-ListItem-secondaryText"&gt;{{service.description}}&lt;/span&gt; 
          &lt;span class="ms-ListItem-tertiaryText"&gt;{{service.version}}&lt;/span&gt; 
          &lt;span class="ms-ListItem-metaText"&gt;{{service.creationTime}}&lt;/span&gt; 
          &lt;a class="ms-Link" (click)="selected(service)"&gt;Select&lt;/a&gt; 
      &lt;/li&gt;
  &lt;/ul&gt;
  
  &lt;div *ngIf="selectedService"&gt;
      &lt;app-web-service [service]="selectedService"&gt;&lt;/app-web-service&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>web-service.component.ts</p>
  
  <pre><code>export class WebServiceComponent implements OnInit {
    @Input() service: WebService;
  
    serviceForm: FormGroup;
  
    constructor(private fb: FormBuilder, private excelService: ExcelService) { 
      this.createForm();
    }
  
    ngOnInit() {
  
    }
  
    createForm() {
      this.serviceForm = this.fb.group({
        inputParameters: this.fb.array([]),
        outputParameters: this.fb.array([])
      });
    }
  
    ngOnChanges() {
      this.setParameters()
    }
  
    setParameters() {
      console.log(this.service.inputParameterDefinitions);
      const inputParameters = this.service.inputParameterDefinitions.map(input =&gt; this.fb.group(input));
      const inputParametersFormArray = this.fb.array(inputParameters);
      this.serviceForm.setControl('inputParameters', inputParametersFormArray);
  
      console.log(this.serviceForm.controls);
  
      const outputParameters = this.service.outputParameterDefinitions.map(output =&gt; this.fb.group(output));
      const outputParametersFormArray = this.fb.array(outputParameters);
      this.serviceForm.setControl('outputParameters', outputParametersFormArray);
    }
  </code></pre>
  
  <p>web-service.component.html</p>
  
  <pre><code>&lt;form [formGroup]="serviceForm" (ngSubmit)="onSubmit()" novalidate&gt;
      &lt;!-- Service Controls --&gt;
      &lt;div formArrayName="inputParameters"&gt;
          &lt;div *ngFor="let parameter of inputParameters.controls; let i=index" [formGroupName]="i"&gt;
              &lt;!--The repeated parameter template--&gt;
              &lt;div&gt;
                  &lt;label&gt;Name:
                      &lt;input formControlName="name"&gt;
                  &lt;/label&gt;
              &lt;/div&gt;
              &lt;div&gt;
                  &lt;label&gt;Type:
                      &lt;input formControlName="type"&gt;
                  &lt;/label&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>