Angular报错:TypeError: Type 'any'需有返回迭代器的Symbol.iterator方法
解决「TypeError: Type 'any' must have a Symbol.iterator method that returns an iterator」错误
我在实现“用户输入子任务按回车确认,子任务以项目符号列表展示”的功能时,遇到了标题所示错误。为保证演示正常编译,已注释掉HTML中的<ul>和<li>元素。
以下是简化代码:
task-form.component.html
<div mat-dialog-title>Create Task</div> <mat-dialog-content> <form [formGroup]="taskForm" (ngSubmit)="onSubmit()"> <mat-form-field> <mat-label>Title</mat-label> <input matInput formControlName="title" type="text" placeholder="Enter a title" /> </mat-form-field> <mat-form-field> <mat-label>Subtasks</mat-label> <input matInput formControlName="subtasks" type="text" placeholder="Enter a subtask" /> <button mat-icon-button matSuffix (keydown.enter)="addSubtask()" (click)="addSubtask()" > <mat-icon>add</mat-icon> </button> <div class="vertical-divider" matSuffix></div> <button mat-icon-button matSuffix (click)="clearSubtask()"> <mat-icon>close</mat-icon> </button> <mat-hint>Press enter to add a subtask</mat-hint> </mat-form-field> </form> <!-- SHOW HERE ALL SUBTASKS--> <!-- <ul> @for (subtask of subtasksFormControl.value; track subtask.id){ <li> {{ subtask }} <button mat-icon-button (click)="editSubtask(subtask)"> <mat-icon>edit</mat-icon> </button> <button mat-icon-button (click)="deleteSubtask(subtask)"> <mat-icon>delete</mat-icon> </button> </li> } </ul>--> </mat-dialog-content> <mat-dialog-actions> <button (click)="onSubmit()" mat-raised-button color="primary" type="submit"> Create Task </button> </mat-dialog-actions>
task-form.component.ts
export class TaskFormComponent { protected readonly Object = Object; taskForm!: FormGroup; fromPopup = false; constructor( private fb: FormBuilder, @Optional() private dialogRef: MatDialogRef<TaskFormComponent>, @Optional() @Inject(MAT_DIALOG_DATA) public data: { fromPopup: boolean; task: Task } ) {} ngOnInit() { this.fromPopup = !!this.data?.fromPopup; this.taskForm = this.fb.group({ id: this.data?.task?.id, title: new FormControl(''), subtasks: new FormControl([]), }); if (this.data?.task) { this.taskForm.patchValue({ id: this.data.task?.id, title: this.data.task.title, subTasks: this.data.task.subtasks, }); } } public get subtasksFormControl() { return this.taskForm.get('subtasks') as FormControl; } public addSubtask() { this.taskForm.value.subtasks; console.log(this.taskForm.value.subtasks); } public clearSubtask() { this.taskForm.patchValue({ subtasks: '' }); } }
错误原因及修复方案
1. 核心问题:数据类型不一致
- 初始化时
subtasks是数组类型,但clearSubtask方法将其设为空字符串'',导致模板中@for循环尝试迭代非可迭代的字符串类型,触发TypeError。 - 输入框直接绑定到
subtasks数组控件,用户输入的字符串会覆盖数组,进一步加剧类型混乱。
2. 分步修复
(1)拆分输入与存储控件
将输入新子任务的控件和存储子任务数组的控件分离,避免类型冲突:
修改task-form.component.ts中的ngOnInit方法:
this.taskForm = this.fb.group({ id: this.data?.task?.id, title: new FormControl(''), newSubtask: new FormControl(''), // 新增:专门用于输入新子任务 subtasks: new FormControl([]), });
对应修改HTML中的输入框formControlName:
<input matInput formControlName="newSubtask" type="text" placeholder="Enter a subtask" />
(2)完善addSubtask方法
实现真正的添加子任务逻辑,同时清空输入框:
public get newSubtaskControl() { return this.taskForm.get('newSubtask') as FormControl; } public addSubtask() { const newSubtask = this.newSubtaskControl.value.trim(); if (!newSubtask) return; // 复制现有子任务数组并添加新项(带唯一id用于track) const updatedSubtasks = [...(this.subtasksFormControl.value || [])]; updatedSubtasks.push({ id: Date.now(), name: newSubtask }); this.subtasksFormControl.setValue(updatedSubtasks); this.newSubtaskControl.setValue(''); // 清空输入框 }
(3)修复clearSubtask方法
将清空逻辑改为重置数组而非字符串:
public clearSubtask() { this.subtasksFormControl.setValue([]); }
(4)修正模板循环与回显逻辑
- 取消注释
<ul>部分,调整显示字段为子任务的name属性:
<ul> @for (subtask of subtasksFormControl.value; track subtask.id){ <li> {{ subtask.name }} <button mat-icon-button (click)="editSubtask(subtask)"> <mat-icon>edit</mat-icon> </button> <button mat-icon-button (click)="deleteSubtask(subtask)"> <mat-icon>delete</mat-icon> </button> </li> } </ul>
- 修复
patchValue中的键名错误(subTasks改为subtasks),确保已有子任务正确回显:
if (this.data?.task) { this.taskForm.patchValue({ id: this.data.task?.id, title: this.data.task.title, subtasks: this.data.task.subtasks, // 修正键名大小写 }); }
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

