You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular NG02200错误求助:NgFor无法绑定非可迭代对象

解决Angular中NgFor绑定对象的NG02200错误

问题场景

使用Angular服务从MongoDB获取作业列表时,触发以下错误:

Angular:ERROR Error: NG02200: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables

问题出在getAssignments()方法,以下是相关代码:

我的Service

import {Injectable} from '@angular/core';
import {Assignment} from '../assignments/assignment.model';
import {Observable, of} from 'rxjs';
import {LoggingService} from './logging.service';
import {HttpClient} from '@angular/common/http';
import {toArray} from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AssignmentsService {
  assignments: Assignment[] = [
    {
      id: 1,
      nom: 'Assignment 1',
      dateRendu: new Date('2020-12-01'),
      rendu: true,
      auteur: 'Asmaa',
      note: 12,
      remarques: 'tres bien'
    },
    {
      id: 2,
      auteur: 'Asmaa',
      note: 14,
      remarques: 'bien',
      nom: 'Assignment 2',
      dateRendu: new Date('2020-12-02'),
      rendu: true,
    },
    {
      id: 3,
      nom: 'Assignment 3',
      dateRendu: new Date('2020-12-03'),
      rendu: false,
      auteur: 'Manel',
      note: 14,
      remarques: 'bien',
    },
  ];

  constructor(private loggingService: LoggingService,
              private http: HttpClient
  ) {
  }

  uri = 'http://localhost:8010/api/assignments'

  getAssignments() {
    return this.http.get<Assignment>(this.uri)
  }

  getAssignment(id: number): Observable<Assignment | undefined> {
    return this.http.get<Assignment>(this.uri + "/" + id)
  }

  addAssignment(assignment: Assignment): Observable<any> {
    console.log('done');
    return this.http.post(this.uri, assignment);
  }

  deleteAssignment(assignment: Assignment): Observable<string> {
    this.loggingService.log(assignment, "supprimé");
    this.assignments.forEach((a, index) => {
        if (a === assignment) {
          this.assignments.splice(index, 1);
        }
      }
    );
    return of('assignement supprimé');
  }

  updateAssignment(assignment: Assignment): Observable<string> {
    this.assignments.forEach((a, index) => {
      if (assignment === a) {
        this.assignments[index] = a;
      }
    });
    return of('assignement modifié');
  }
}

我的HTML

<a routerLink="/add">
  <button mat-raised-button color="primary">Ajouter un devoir</button>
</a>

<mat-list *ngFor="let assignment of assignments ">
  <nav>
    <a routerLink="/assignment/{{this.assignment.id}}">
      <mat-list-item (click)="assignmentCliquer(assignment)">
        <p *ngIf="assignment.rendu; else nonsoumis">
          Devoir intitulé {{ assignment.nom }}, rendu le
          {{ assignment.dateRendu }}.
        </p>
        <ng-template #nonsoumis>
          Le devoir {{ assignment.nom }} n'a pas été rendu.
        </ng-template>
        <mat-divider></mat-divider>
      </mat-list-item>
    </a>
  </nav>
</mat-list>

我的Component

import {Component, OnInit} from '@angular/core';
import {AssignmentsService} from '../shared/assignments.service';
import {Assignment} from './assignment.model';

@Component({
  selector: 'app-assignments',
  templateUrl: './assignments.component.html',
  styleUrls: ['./assignments.component.css'],
})
export class AssignmentsComponent implements OnInit {
  titre = 'Liste des Assignments';
  ajoutActive = false;
  formActive = false;
  nomDevoir: string = '';
  dateDevoir: Date = new Date();
  assignmentSelectionne!: Assignment;
  assignments!: Assignment[];

  constructor(private assignmentsService: AssignmentsService) {
  }

  ngOnInit(): void {
    this.getAssignments();
  }

  getAssignments() {
    this.assignmentsService.getAssignments().subscribe(
      (assignments: any) => {
        this.assignments = assignments;
      }
    );
  }

  assignmentCliquer(assignment: Assignment) {
    this.assignmentSelectionne = assignment;
  }
}

错误原因

  1. 服务返回类型错误:getAssignments()方法声明返回Observable<Assignment>(单个作业对象),但实际后端应返回作业数组Assignment[],类型不匹配导致赋值错误。
  2. 后端数据结构可能是包装对象:多数MongoDB后端会返回包含数组的包装对象(比如{ data: [Assignment] }),而非直接数组,直接将响应赋值给assignments变量会导致NgFor遍历对象而非数组。
  3. HTML模板变量错误:routerLink="/assignment/{{this.assignment.id}}"中的this.assignment无效,ngFor循环中应直接使用循环变量assignment。

解决方案

步骤1:修正Service的返回类型

修改getAssignments()方法,确保返回数组类型的Observable:

// 导入map操作符
import { map } from 'rxjs/operators';

getAssignments(): Observable<Assignment[]> {
  // 情况1:后端直接返回作业数组
  return this.http.get<Assignment[]>(this.uri);
  
  // 情况2:后端返回包装对象(如{ data: Assignment[] }),需提取数组
  // return this.http.get<any>(this.uri).pipe(
  //   map(response => response.data)
  // );
}

注:需先通过Postman等工具确认后端实际返回的数据格式,选择对应写法。

步骤2:Component中正确处理响应

如果后端返回包装对象,订阅时提取数组:

getAssignments() {
  this.assignmentsService.getAssignments().subscribe(
    (assignments) => {
      this.assignments = assignments;
    },
    (error) => {
      console.error('获取作业列表失败:', error);
    }
  );
}

步骤3:修复HTML模板变量错误

将this.assignment.id改为assignment.id:

<a routerLink="/assignment/{{assignment.id}}">

可选:初始化assignments为空数组

避免初始时assignments为undefined的潜在问题,在Component中初始化数组:

assignments: Assignment[] = [];

验证

修改完成后,重启Angular应用并确保后端服务正常运行,此时NgFor可正常遍历作业数组,错误消失。

内容的提问来源于stack exchange,提问作者ASMAA HAIDOUR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:10:40