为什么我在订阅 patientAllergies observable 时会收到以下错误?
Why am I receiving the following error when subscribed to the patientAllergies observable?
当我select在patient-allergies.component.ts、select选项中添加patient allergy并点击save时,我收到如下错误:
错误错误:尝试区分“[object Object]”时出错。只允许数组和可迭代对象。
当我将对象从 rest-api.service.ts 通过 _patientAllergies.next() 传递到数组时,我无法理解为什么会收到此错误。
患者-allergies.component.html
<mat-card class="mat-typography">
<mat-card-title>Allergies</mat-card-title>
<mat-card-content>
<hr>
<div *ngFor="let patientAllergy of this.patientAllergies">
<h3 *ngIf="!patientAllergy.nickname"> {{ patientAllergy.fullname }} </h3>
<h3 *ngIf="patientAllergy.nickname"> {{ patientAllergy.fullname }} ({{ patientAllergy.nickname }}) </h3>
</div>
</mat-card-content>
<mat-card-actions *ngIf="isEdit">
<button mat-button class="dark" (click)="onAdd()">ADD</button>
<button mat-button class="dark" (click)="onRemove()">REMOVE</button>
</mat-card-actions>
</mat-card>
<mat-card *ngIf="isLoading" style="display: flex; justify-content: center; align-items: center">
<mat-progress-spinner class="mat-spinner-color" mode="indeterminate"></mat-progress-spinner>
</mat-card>
患者-allergies.component.ts
import {Component, OnInit, Input, Pipe, PipeTransform} from '@angular/core';
import {RestAPIService} from 'src/app/rest-api.service';
import {ActivatedRoute} from '@angular/router';
import {MatDialog} from '@angular/material';
@Component({selector: 'app-patient-allergies', templateUrl: './patient-allergies.component.html', styleUrls: ['./patient-allergies.component.css']})
export class PatientAllergiesComponent implements OnInit {
@Input()isEdit : boolean = false;
constructor(private restAPIService : RestAPIService, private route : ActivatedRoute, public dialog : MatDialog) {}
isLoading : boolean;
patientAllergies;
subscription = null;
ngOnInit() {
this.isLoading = true;
this
.restAPIService
.getPatientAllergies(this.route.snapshot.params.id);
this.subscription = this
.restAPIService
.patientAllergies
.subscribe((patAllergies) => {
this.patientAllergies = patAllergies as [];
this.isLoading = false;
});
}
onAdd() {
let dRef = this
.dialog
.open(AllergiesDialogComponent, {
disableClose: true,
height: '800px',
width: '600px',
data: {
isAdding: true,
patientAllergies: this.patientAllergies
}
});
dRef
.afterClosed()
.subscribe((res) => {
res.forEach((ele) => {
this
.restAPIService
.addPatientAllergies(this.route.snapshot.params.id, ele.value.allergyID);
});
});
}
onRemove() {
let dRef = this
.dialog
.open(AllergiesDialogComponent, {
disableClose: true,
height: '800px',
width: '600px',
data: {
isAdding: false,
patientAllergies: this.patientAllergies
}
});
dRef
.afterClosed()
.subscribe((res) => {
res.forEach((ele) => {
this
.restAPIService
.deletePatientAllergies(this.route.snapshot.params.id, ele.value.allergyID);
});
})
}
}
import {Inject} from '@angular/core';
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
import {DialogData} from 'src/app/patient/patient.component';
@Component({selector: 'app-allergies-dialog', templateUrl: './allergies-dialog.component.html', styleUrls: ['./allergies-dialog.component.css']})
export class AllergiesDialogComponent implements OnInit {
allergies = [];
filterName : string;
subscription;
constructor(public dialogRef : MatDialogRef < AllergiesDialogComponent >, @Inject(MAT_DIALOG_DATA)public data : DialogData, private restAPIService : RestAPIService) {}
ngOnInit() {
this
.restAPIService
.getAllergies();
if (this.data['isAdding']) {
this.subscription = this
.restAPIService
.allergies
.subscribe((allergies) => {
let allergiesArr = allergies as [];
this.allergies = [];
let patientAllergyNames = [];
this
.data['patientAllergies']
.forEach(patientAllergy => {
patientAllergyNames.push(patientAllergy['fullname'])
});
allergiesArr.forEach(allergy => {
if (!patientAllergyNames.includes(allergy['fullname']))
this.allergies.push(allergy);
}
);
})
} else {
this.allergies = this.data['patientAllergies'];
}
}
onClose(selectedOptions) {
if (this.data['isAdding'])
this.subscription.unsubscribe();
// either [] or the IDs of the objects to add/remove
this
.dialogRef
.close(selectedOptions);
}
}
@Pipe({name: 'filterOnName'})
export class filterNames implements PipeTransform {
transform(listOfObjects : any, nameToFilter : string) : any {
let allergyArr = listOfObjects as[];
let matchedObjects = [];
if (!listOfObjects)
return null;
if (!nameToFilter)
return listOfObjects;
allergyArr.forEach(allergyObj => {
let fullname : string = allergyObj['fullname'];
let nickname : string = allergyObj['nickname'];
let fullnameLower = fullname.toLowerCase();
let nicknameLower = fullname.toLowerCase();
let filter = nameToFilter.toLowerCase();
if (nickname) {
if ((fullnameLower.includes(filter) || nicknameLower.includes(filter)))
matchedObjects.push(allergyObj);
}
else {
if (fullnameLower.includes(filter))
matchedObjects.push(allergyObj);
}
});
return matchedObjects;
}
}
休息-api.service.ts
private _allergies;
private allergiesSubject = new Subject();
allergies = this
.allergiesSubject
.asObservable();
private _patientAllergies;
private patientAllergiesSubject = new Subject();
patientAllergies = this
.patientAllergiesSubject
.asObservable();
getPatientAllergies(patientID) {
const request = {
headers: {},
response: true
};
API
.get('DiagnetAPI', '/v1/patients/' + patientID + '/allergies', request)
.then(resp => {
this._patientAllergies = resp.data;
this
.patientAllergiesSubject
.next(this._patientAllergies);
})
.catch((err) => console.log(err))
}
addPatientAllergies(patientID, allergyID) {
const request = {
headers: {},
response: true,
body: allergyID
};
API
.post('DiagnetAPI', '/v1/patients/' + patientID + '/allergies', request)
.then(resp => {
console.log(resp.data);
this._patientAllergies = resp.data;
this
.patientAllergiesSubject
.next(this._patientAllergies);
})
.then(() => {
this.getPatientAllergies(patientID);
})
.catch((err) => console.log(err))
}
deletePatientAllergies(patientID, allergyID) {
const request = {
headers: {},
response: true
};
API
.del('DiagnetAPI', '/v1/patients/' + patientID + '/allergies/' + allergyID, request)
.then((res) => console.log(res))
.then(() => {
this.getPatientAllergies(patientID);
})
.catch((err) => console.log(err))
}
如果 api 的响应不是数组而是对象,则可以在 *ngFor 循环中使用 keyvalue
管道。
在您的情况下 patientAllergy
将是一个具有两个键的对象, key
和 value
因此您可以像这样访问昵称: patientAllergy.value.nickname
您的模板:
<div *ngFor="let patientAllergy of this.patientAllergies | keyvalue">
<h3 *ngIf="!patientAllergy.value.nickname"> {{ patientAllergy.value.fullname }} </h3>
<h3 *ngIf="patientAllergy.value.nickname"> {{ patientAllergy.value.fullname }} ({{ patientAllergy.value.nickname }}) </h3>
</div>
当我select在patient-allergies.component.ts、select选项中添加patient allergy并点击save时,我收到如下错误:
错误错误:尝试区分“[object Object]”时出错。只允许数组和可迭代对象。
当我将对象从 rest-api.service.ts 通过 _patientAllergies.next() 传递到数组时,我无法理解为什么会收到此错误。
患者-allergies.component.html
<mat-card class="mat-typography">
<mat-card-title>Allergies</mat-card-title>
<mat-card-content>
<hr>
<div *ngFor="let patientAllergy of this.patientAllergies">
<h3 *ngIf="!patientAllergy.nickname"> {{ patientAllergy.fullname }} </h3>
<h3 *ngIf="patientAllergy.nickname"> {{ patientAllergy.fullname }} ({{ patientAllergy.nickname }}) </h3>
</div>
</mat-card-content>
<mat-card-actions *ngIf="isEdit">
<button mat-button class="dark" (click)="onAdd()">ADD</button>
<button mat-button class="dark" (click)="onRemove()">REMOVE</button>
</mat-card-actions>
</mat-card>
<mat-card *ngIf="isLoading" style="display: flex; justify-content: center; align-items: center">
<mat-progress-spinner class="mat-spinner-color" mode="indeterminate"></mat-progress-spinner>
</mat-card>
患者-allergies.component.ts
import {Component, OnInit, Input, Pipe, PipeTransform} from '@angular/core';
import {RestAPIService} from 'src/app/rest-api.service';
import {ActivatedRoute} from '@angular/router';
import {MatDialog} from '@angular/material';
@Component({selector: 'app-patient-allergies', templateUrl: './patient-allergies.component.html', styleUrls: ['./patient-allergies.component.css']})
export class PatientAllergiesComponent implements OnInit {
@Input()isEdit : boolean = false;
constructor(private restAPIService : RestAPIService, private route : ActivatedRoute, public dialog : MatDialog) {}
isLoading : boolean;
patientAllergies;
subscription = null;
ngOnInit() {
this.isLoading = true;
this
.restAPIService
.getPatientAllergies(this.route.snapshot.params.id);
this.subscription = this
.restAPIService
.patientAllergies
.subscribe((patAllergies) => {
this.patientAllergies = patAllergies as [];
this.isLoading = false;
});
}
onAdd() {
let dRef = this
.dialog
.open(AllergiesDialogComponent, {
disableClose: true,
height: '800px',
width: '600px',
data: {
isAdding: true,
patientAllergies: this.patientAllergies
}
});
dRef
.afterClosed()
.subscribe((res) => {
res.forEach((ele) => {
this
.restAPIService
.addPatientAllergies(this.route.snapshot.params.id, ele.value.allergyID);
});
});
}
onRemove() {
let dRef = this
.dialog
.open(AllergiesDialogComponent, {
disableClose: true,
height: '800px',
width: '600px',
data: {
isAdding: false,
patientAllergies: this.patientAllergies
}
});
dRef
.afterClosed()
.subscribe((res) => {
res.forEach((ele) => {
this
.restAPIService
.deletePatientAllergies(this.route.snapshot.params.id, ele.value.allergyID);
});
})
}
}
import {Inject} from '@angular/core';
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
import {DialogData} from 'src/app/patient/patient.component';
@Component({selector: 'app-allergies-dialog', templateUrl: './allergies-dialog.component.html', styleUrls: ['./allergies-dialog.component.css']})
export class AllergiesDialogComponent implements OnInit {
allergies = [];
filterName : string;
subscription;
constructor(public dialogRef : MatDialogRef < AllergiesDialogComponent >, @Inject(MAT_DIALOG_DATA)public data : DialogData, private restAPIService : RestAPIService) {}
ngOnInit() {
this
.restAPIService
.getAllergies();
if (this.data['isAdding']) {
this.subscription = this
.restAPIService
.allergies
.subscribe((allergies) => {
let allergiesArr = allergies as [];
this.allergies = [];
let patientAllergyNames = [];
this
.data['patientAllergies']
.forEach(patientAllergy => {
patientAllergyNames.push(patientAllergy['fullname'])
});
allergiesArr.forEach(allergy => {
if (!patientAllergyNames.includes(allergy['fullname']))
this.allergies.push(allergy);
}
);
})
} else {
this.allergies = this.data['patientAllergies'];
}
}
onClose(selectedOptions) {
if (this.data['isAdding'])
this.subscription.unsubscribe();
// either [] or the IDs of the objects to add/remove
this
.dialogRef
.close(selectedOptions);
}
}
@Pipe({name: 'filterOnName'})
export class filterNames implements PipeTransform {
transform(listOfObjects : any, nameToFilter : string) : any {
let allergyArr = listOfObjects as[];
let matchedObjects = [];
if (!listOfObjects)
return null;
if (!nameToFilter)
return listOfObjects;
allergyArr.forEach(allergyObj => {
let fullname : string = allergyObj['fullname'];
let nickname : string = allergyObj['nickname'];
let fullnameLower = fullname.toLowerCase();
let nicknameLower = fullname.toLowerCase();
let filter = nameToFilter.toLowerCase();
if (nickname) {
if ((fullnameLower.includes(filter) || nicknameLower.includes(filter)))
matchedObjects.push(allergyObj);
}
else {
if (fullnameLower.includes(filter))
matchedObjects.push(allergyObj);
}
});
return matchedObjects;
}
}
休息-api.service.ts
private _allergies;
private allergiesSubject = new Subject();
allergies = this
.allergiesSubject
.asObservable();
private _patientAllergies;
private patientAllergiesSubject = new Subject();
patientAllergies = this
.patientAllergiesSubject
.asObservable();
getPatientAllergies(patientID) {
const request = {
headers: {},
response: true
};
API
.get('DiagnetAPI', '/v1/patients/' + patientID + '/allergies', request)
.then(resp => {
this._patientAllergies = resp.data;
this
.patientAllergiesSubject
.next(this._patientAllergies);
})
.catch((err) => console.log(err))
}
addPatientAllergies(patientID, allergyID) {
const request = {
headers: {},
response: true,
body: allergyID
};
API
.post('DiagnetAPI', '/v1/patients/' + patientID + '/allergies', request)
.then(resp => {
console.log(resp.data);
this._patientAllergies = resp.data;
this
.patientAllergiesSubject
.next(this._patientAllergies);
})
.then(() => {
this.getPatientAllergies(patientID);
})
.catch((err) => console.log(err))
}
deletePatientAllergies(patientID, allergyID) {
const request = {
headers: {},
response: true
};
API
.del('DiagnetAPI', '/v1/patients/' + patientID + '/allergies/' + allergyID, request)
.then((res) => console.log(res))
.then(() => {
this.getPatientAllergies(patientID);
})
.catch((err) => console.log(err))
}
如果 api 的响应不是数组而是对象,则可以在 *ngFor 循环中使用 keyvalue
管道。
在您的情况下 patientAllergy
将是一个具有两个键的对象, key
和 value
因此您可以像这样访问昵称: patientAllergy.value.nickname
您的模板:
<div *ngFor="let patientAllergy of this.patientAllergies | keyvalue">
<h3 *ngIf="!patientAllergy.value.nickname"> {{ patientAllergy.value.fullname }} </h3>
<h3 *ngIf="patientAllergy.value.nickname"> {{ patientAllergy.value.fullname }} ({{ patientAllergy.value.nickname }}) </h3>
</div>