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
相关产品推荐
相关产品推荐

