Почему я получаю следующую ошибку при подписке на пациента Наблюдаемые аллергии? - PullRequest
0 голосов
/ 26 марта 2020

Когда я нажимаю кнопку «Добавить» в Patient-аллергии.компонента.ts, выбираю опции для добавления аллергии пациента и нажимаю кнопку «Сохранить», я получаю следующую ошибку:

ОШИБКА Ошибка: ошибка пытаясь diff '[объект объекта]'. Разрешены только массивы и итерации.

Я не могу понять, почему я получаю эту ошибку, когда я преобразовываю объект в массив, когда он передается из rest-api.service.ts через _patientAllergies.next ().

пациент-аллергии.компонент. 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>

пациент-аллергии.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;
    }
}

rest-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))
}

1 Ответ

1 голос
/ 26 марта 2020

Если ваш ответ от API - это не массив, а объект, вы можете использовать keyvalue канал в вашем * ngFor l oop. В вашем случае 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>
...