无法在角度应用程序中调试“ ERROR TypeError:无法读取属性'forEach'为空”的错误

时间:2019-09-16 07:10:00

标签: angular angular-reactive-forms angular-forms

我最近开始学习angular并创建了这种反应形式,该形式需要用户的一些输入。但是,“爱好”部分无法正常工作,我遇到了无法调试的错误:

AppComponent.html:39 ERROR TypeError: Cannot read property 'forEach' of null
    at FormArray._forEachChild (forms.js:5718)
    at FormArray._setUpControls (forms.js:5759)
    at new FormArray (forms.js:5385)
    at AppComponent.onAddHobby (app.component.ts:30)
    at Object.eval [as handleEvent] (AppComponent.html:42)
    at handleEvent (core.js:43992)
    at callWithDebugContext (core.js:45631)
    at Object.debugHandleEvent [as handleEvent] (core.js:45246)
    at dispatchEvent (core.js:29803)
    at core.js:42924

这是html和.ts文件:

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form [formGroup]="signupForm" (ngSubmit) = "onSubmit()">
        <div formGroupName="userData">
          <div class="form-group">
            <label for="username">Username</label>
            <input
              type="text"
              id="username"
              formControlName="username"
              class="form-control">
              <span 
              *ngIf="!signupForm.get('userData.username').valid && signupForm.get('userData.username').touched"
              class="help-block">Invalid Username!</span>
          </div>
          <div class="form-group">
            <label for="email">email</label>
            <input
              type="text"
              id="email"
              formControlName="email"
              class="form-control">
              <span 
              *ngIf="!signupForm.get('userData.email').valid && signupForm.get('userData.email').touched"
              class="help-block">Invalid Email!</span>
          </div>
        </div>
        <div class="radio" *ngFor="let gender of genders">
          <label>
            <input
              type="radio"
              formControlName="gender"
              [value]="gender">{{ gender }}
          </label>
        </div>
        <div formArrayName="hobbies">
          <h4>Your hobbies:</h4>
          <button 
          class="btn btn-default" 
          type="button"
          (click)="onAddHobby()">Add Hobby</button>
          <hr>
          <div 
          class="form-group"
          *ngFor="let hobbyControl of getControls(); let i = index">
          <input type="text" class="form-control" [formControlName]="i">
          </div>
        </div>
        <span 
            *ngIf="!signupForm.valid && signupForm.touched"
            class="help-block">Invalid Data!</span>
        <button class="btn btn-primary" type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

我认为这里的问题出在我的addHobby()函数上,Chrome调试器在按钮标签上抛出了一个错误,因为当我单击它时会发生错误。

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  genders = ['Male', 'Female'];
  signupForm: FormGroup;

  ngOnInit() {
    this.signupForm = new FormGroup({
      'userData': new FormGroup({
        'username': new FormControl(null, Validators.required),
        'email': new FormControl(
          null, [Validators.required, Validators.email])
      }),
      'gender': new FormControl('Male'),
      'hobbies': new FormArray([])
    });
  }

  onSubmit() {
    console.log(this.signupForm);
  }

  onAddHobby() {
    const control = new FormArray(null, Validators.required);
    (<FormArray>this.signupForm.get('hobbies')).push(control);
  }

  getControls() {
    return (<FormArray>this.signupForm.get('hobbies')).controls;
  }
}

请在这里帮助我。

2 个答案:

答案 0 :(得分:2)

罪魁祸首是这条线:

const control = new FormArray(null, Validators.required);

您正在将null传递给FormArray的构造函数,该构造函数需要一个数组。有关详情,请参见此链接:https://angular.io/api/forms/FormArray

由于值为null,因此无法在其上调用函数forEach

答案 1 :(得分:0)

如其他答案中所述,错误来自将control声明为空FormArray。无论如何,我什至看不到它应该是FormArray,假设根据您的模板,它应该是FormControl

onAddHobby() {
  const control = new FormControl(null, Validators.required);
  (<FormArray>this.signupForm.get('hobbies')).push(control);
}

STACKBLITZ

PS:我认为使用FormBuilder比使用new FormArray([]) / new FormGroup({...})更为简洁