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

Angular中*ngFor遍历对象报错:仅允许数组/可迭代对象

解决Angular中*ngFor遍历对象导致的"Error trying to diff '[object Object]'"错误

在Angular项目中使用*ngFor渲染历史就诊记录选项时,触发如下错误:

Error trying to diff '[object Object]'. Only arrays and iterables are allowed

尝试通过response.data获取返回数据后错误仍存在,以下是问题排查和解决方法:

API返回的JSON数据

{
  "expires_in": 0,
  "data": {
    "patientEncounterTemplate": [
      {
        "id": 2,
        "patientEncounterId": 2,
        "masterTemplateId": 1,
        "templateData": "",
        "templateJson": "",
        "isDeleted": false
      }
    ],
    "id": 2,
    "patientID": 6,
    "patientAppointmentId": 60,
    "dateOfService": "2021-03-02T12:00:00",
    "startDateTime": "2021-03-02T12:00:00",
    "endDateTime": "2021-03-02T13:00:00",
    "appointmentStartDateTime": "0001-01-01T00:00:00",
    "appointmentEndDateTime": "0001-01-01T00:00:00",
    "staffID": 10,
    "officeAddressID": 1,
    "serviceLocationID": 1,
    "notetypeId": 1,
    "staffName": "Staff 1",
    "patientName": "Rahul Singh",
    "locationName": "Eveda",
    "status": "Pending",
    "totalRecords": 0,
    "unitsBlocked": 0,
    "unitsConsumed": 0,
    "serviceFacility": "62 - Comprehensive Outpatient ",
    "isDirectService": true,
    "isBillableEncounter": false,
    "soapNotes": {
      "id": 2,
      "subjective": "",
      "objective": "",
      "assessment": "",
      "plans": ""
    },
    "patientEncounterServiceCodes": [],
    "patientEncounterDiagnosisCodes": [],
    "encounterSignature": []
  },
  "message": "Success",
  "statusCode": 200,
  "appError": "",
  "firstTimeLogin": false,
  "openDefaultClient": false
}

相关代码

选择历史就诊记录的TS代码

getSelectedPreviousEncountersData(event:any){
    debugger
   this.previousEncounterId = event;
   this.encounterService.getPreviousEncountersData(this.previousEncounterId)
   .subscribe(
     response => {
       if (response.statusCode == 200) {
        debugger
         this.previousEncounters=response.data;
         if (response.statusCode == 200) {
          debugger
          console.log(this.previousEncounters)
          this.isPreviousEncounter=true;
          this.encounterId=0;
          this.soapNotes = response.data.soapNotes || null;
          this.patientEncounterTemplate = response.data.patientEncounterTemplate || [];
          this.templateFormId = response.data.patientEncounterTemplate && 
          response.data.patientEncounterTemplate[0].masterTemplateId || 0;

        } else {
          this.soapNotes = null;
          this.unitsConsumed = 0;
          this.isSoapCompleted = false;
        }
        debugger
        if (this.previousEncounterId) {
          this.getTemplateForm(this.templateFormId);
        }
       }
     }
   )
  }

HTML模板代码

<div class="col-sm-3">
    <div class="form-group">
        <mat-form-field class="example-full-width">
            <mat-select placeholder="Select Previous Encounters"
                [(value)]="previousEncounterId"
                (selectionChange)="getSelectedPreviousEncountersData($event.value)">
                <mat-option *ngFor="let encounter of previousEncounters"
                    [value]="encounter.id">
                    {{ encounter.dateOfService }}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </div>
</div>
<div class="col-sm-3 ">
    <div class="filter-btn d-flex justify-content-end">
        <button type="button" class="rounded px-1" color="warn"
            mat-raised-button (click)="clearFilters()">Clear All</button>
        <button name="Filter" mat-raised-button class="rounded px-1 ml-3"
            color="accent" (click)="applyFilter()">Filter</button>
    </div>
</div>

筛选功能相关TS代码

applyFilter() {
    debugger
    let formValues = this.soapForm.value;
    this.getPreviousEncounters(this.patientAppointmentDetails.patientID, formValues.fromDate ? format(formValues.fromDate, 'MM/DD/YYYY') : "", formValues.toDate ? format(formValues.toDate, 'MM/DD/YYYY') : "");
  }

getPreviousEncounters(patientId, fromDate, toDate){

    this.encounterService.getPreviousEncounters(patientId, fromDate, toDate)
    .subscribe(
      response => {
        if (response.statusCode == 200) {
          this.previousEncounters=response.data;
          this.previousEncounterId=response.data.id;
          this.previousEncounters = (response.data || []).map((obj: any) => {
            obj.dateOfService = format(obj.dateOfService, 'MM/DD/YYYY hh:mm a');
            return obj;
          });

          //Legasov Added
          ////this.changeDetector.detectChanges();
        }
        else{
          this.previousEncounters=[];
        }
      }
    )
  }

问题原因

错误本质是*ngFor指令只能遍历数组或可迭代对象,但当前代码中previousEncounters被赋值为单个对象(API返回的response.data是单个就诊记录对象,而非数组),导致Angular无法对其进行遍历渲染。

解决方法

方法1:将单个对象包装为数组

在赋值previousEncounters时,把单个对象转为数组格式,确保*ngFor可以正常遍历:

修改getSelectedPreviousEncountersData中的赋值逻辑:

// 原代码
// this.previousEncounters=response.data;

// 修改后
this.previousEncounters = [response.data]; // 将单个对象包装成数组

修改getPreviousEncounters中的赋值逻辑:

// 原代码
// this.previousEncounters = (response.data || []).map((obj: any) => { ... });

// 修改后
this.previousEncounters = [response.data].map((obj: any) => {
  obj.dateOfService = format(obj.dateOfService, 'MM/DD/YYYY hh:mm a');
  return obj;
});

方法2:检查后端接口返回格式

如果业务逻辑中getPreviousEncounters应该返回多条就诊记录,需要确认后端接口是否返回了数组格式的response.data。若后端错误返回了单个对象,需调整后端接口返回数组(即使只有一条数据)。


内容的提问来源于stack exchange,提问作者Mike Micky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:10:27