Приложение MEAN с ошибкой angular 2: не удается прочитать свойство _id неопределенного

Я впервые создаю приложение для хранения, обновления, просмотра и удаления профилей клиентов. Я следил за Angular-туром по героям, чтобы создать базовое приложение, а затем собрал mongodb по кусочкам и выразил части со всего Интернета.

Я получаю эту ошибку в консоли своего браузера, когда пытаюсь удалить профиль клиента -

ОШИБКА Тип: Ошибка: невозможно прочитать свойство _id для undefined в ClientProfileComp.webpackJsonp ... / .. / .. / .. / .. / src / app / components / clientProfile.component.ts.ClientProfileComp.delete (clientProfile.component .ts: 53) ... (и т. д.).

Я подтвердил через почтальона, что моя экспресс-маршрутизация работает должным образом. Я могу получать / создавать клиентов в /api/clients, а также получать, помещать и удалять из /api/clients/:_id (где _id - автоматически сгенерированный идентификатор для каждой записи).

Я считаю, что проблема в одном из моих файлов компонентов, поскольку ошибка возникает только тогда, когда я пытаюсь удалить или просмотреть конкретную информацию о клиенте, что полностью вызывает другой тип ошибки (CastError). Проблема, вероятно, началась, когда я попытался удалить все упоминания clientProfile: ClientProfile[]; (или Hero в случае учебника), поскольку я больше не импортирую детали из client.ts (hero.ts), поскольку вместо этого я использую схему мангуста, и я это делаю не верю, что мне следует импортировать эту схему в свой интерфейс angular.

вот раздел удаления clientProfile.service.ts:

delete(_id: number): Promise<void>  {
    const url = `${this.clientProfilesUrl}/${_id}`;
    return this.http.delete(url, {headers: this.headers}).toPromise()
    .then(() => null).catch(this.handleError);
}

и вот clientProfile.component.ts по запросу (наиболее вероятный источник моей проблемы в том, что я заменил все экземпляры clientProfile: ClientProfile; на clientProfile: any;, не зная, что я делал), обратите внимание на закомментированный оператор импорта.

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

//import { ClientProfile } from '../old/clientProfile';
import { ClientProfileService } from '../services/clientProfile.service';

@Component({
selector: 'app-clientprofile',
templateUrl: '../views/clientProfile.component.html',
styleUrls: [ '../styles/clientprofile.component.css' ]
})

export class ClientProfileComp implements OnInit {
selectedClientProfile: any;
clientProfiles: any = [];
clientProfile: any;

constructor(
    private clientProfileService: ClientProfileService,
    private router: Router
) { }

gotoDetail(): void {
    this.router.navigate(['/detail', this.selectedClientProfile._id]);
}

getClientProfiles(): void {
    this.clientProfileService.getClientProfiles().then(clientProfiles => {
        this.clientProfiles = clientProfiles;
    });
}

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

onSelect(clientProfile: any): void {
    this.selectedClientProfile = clientProfile;
}

add(name: string, address: string): void {
    name = name.trim();
    address = address.trim();
    if (!name) { return; }
    this.clientProfileService.create(name, address).then(clientProfile => {
        this.clientProfiles.push(clientProfile);
            this.selectedClientProfile = null;
    this.getClientProfiles();
    });
}

delete(clientProfile: any): void {
    this.clientProfileService.delete(clientProfile._id).then(() => {
        this.clientProfiles = this.clientProfiles.filter(h => h !== 
clientProfile);
        if (this.selectedClientProfile === clientProfile) { this.selectedClientProfile = null; }
    });
}
}

Я размышлял над этим весь день и прочитал здесь много похожих постов, но большинство решений, похоже, не применимы к этому случаю. Если бы кто-нибудь мог указать мне правильное направление, я был бы очень благодарен. Если потребуется еще какой-либо код, чтобы объяснить, что я пытаюсь сделать, я с радостью отправлю его.


person KuroKyo    schedule 12.09.2017    source источник
comment
Сама ошибка говорит о том, что она не находит _id в поле undefind, что означает в вашем clientProfile.component.ts, когда вы делаете clientProfile._id в это время clientProfile undefined   -  person ranakrunal9    schedule 12.09.2017
comment
опубликовать полный код вашегоclientProfile.component.ts   -  person ranakrunal9    schedule 12.09.2017
comment
выше код из (clientProfile.component.ts: 53)?   -  person Tarang Rathod    schedule 12.09.2017
comment
@TarangRathod правильно.   -  person KuroKyo    schedule 12.09.2017
comment
@ ranakrunal9 я отредактирую сообщение, чтобы включить полный код этого файла   -  person KuroKyo    schedule 12.09.2017


Ответы (2)


Судя по сообщению об ошибке, кажется, что ошибка здесь:

this.router.navigate(['/detail', this.selectedClientProfile._id])

Похоже, что вы устанавливаете его только в onSelect, и в вашем коде есть несколько мест, где вы устанавливаете this.selectedClientProfile в значение null. Это было бы лучшее место для поиска.

Если вы хотите создать плункер, демонстрирующий вашу проблему, мы могли бы изучить ее подробнее.

В качестве примечания, вы используете обещания вместо теперь более распространенных Observables. Если вы хотите перейти на использование Observables, у меня есть полный пример операций CRUD (создание, чтение, обновление и удаление) здесь: https://github.com/DeborahK/Angular2-ReactiveForms в папке APM.

person DeborahK    schedule 12.09.2017
comment
спасибо, у меня было несколько наблюдаемых / обещающих ошибок во время разработки, я посмотрю на вашу ссылку. - person KuroKyo; 12.09.2017
comment
Это может быть еще лучший ресурс, поскольку он показывает Angular с Mongo и Express: sitepoint.com/mean-stack-angular-2-angular-cli - person DeborahK; 12.09.2017
comment
Когда я активирую gotoDetail, приложение успешно переходит к ожидаемому адресу - /detail/59b1dd167bd6d20e18cf795e, однако не получает ожидаемых результатов с этой страницы, выдавая только CastError. Мне кажется, что это может быть связано с тем, что в какой-то момент он перенаправляется на / detail /: _ id, а не на / api / clients /: _ id. Я рассмотрю это подробнее к концу недели! - person KuroKyo; 12.09.2017

Обнаружена одна проблема - моя кнопка удаления в файле html была в div, который появлялся только при выборе клиента, а не рядом с каждым клиентом. это было результатом незавершенной меры, которую я предпринял, чтобы пользователи не просто волей-неволей нажимали «Удалить» на каждом клиенте.

Код до:

<h2>Client Profiles</h2>
<div class="add-client">
<label>Add new client</label>
<input placeholder="Client Name (required)" #clientProfileName />
<input placeholder="Client Address" #clientProfileAddress />
<button (click)="add(clientProfileName.value, clientProfileAddress.value); 
clientProfileName.value=''; clientProfileAddress.value=''">
    Add</button>
</div>
<ul class="clientProfiles">
<li *ngFor="let clientProfile of clientProfiles"
    [class.selected]="clientProfile === selectedClientProfile"
    (click)="onSelect(clientProfile)">
    <span class="badge">{{clientProfile.idnumber}}</span>
    <span>{{clientProfile.name}}</span>
</li>
</ul>
<div *ngIf="selectedClientProfile">
<h2>
    {{selectedClientProfile.name | uppercase}} selected
</h2>
<button (click)="gotoDetail()">View Details</button>
<button class="delete"
        (click)="delete(clientProfile); 
$event.stopPropagation()">Delete</button>
//delete button will only appear when a client is selected
</div>

Код сейчас:

<h2>Client Profiles</h2>
<div class="add-client">
<label>Add new client</label>
<input placeholder="Client Name (required)" #clientProfileName />
<input placeholder="Client Address" #clientProfileAddress />
<button (click)="add(clientProfileName.value, clientProfileAddress.value); 
clientProfileName.value=''; clientProfileAddress.value=''">
    Add</button>
</div>
<ul class="clientProfiles">
<li *ngFor="let clientProfile of clientProfiles"
    [class.selected]="clientProfile === selectedClientProfile"
    (click)="onSelect(clientProfile)">
    <span class="badge">{{clientProfile.idnumber}}</span>
    <span>{{clientProfile.name}}</span>
    <button class="delete"
        (click)="delete(clientProfile); 
$event.stopPropagation()">Delete</button>
//delete button appears next to each client
</li>
</ul>
<div *ngIf="selectedClientProfile">
<h2>
    {{selectedClientProfile.name | uppercase}} selected
</h2>
<button (click)="gotoDetail()">View Details</button>
</div>
person KuroKyo    schedule 15.09.2017