MEAN app with angular 2 error: Cannot read property _id of undefined
MEAN app with angular 2 error: Cannot read property _id of undefined
我是第一次构建应用程序来存储、更新、查看和删除客户资料。我按照 Angular 英雄之旅构建了基本应用程序,然后拼凑了 mongodb 并表达了来自网络的部分内容。
当我尝试删除客户端配置文件时,我的浏览器控制台出现此错误 -
ERROR TypeError: Cannot read property '_id' of undefined
at ClientProfileComp.webpackJsonp.../../../../../src/app/components/clientProfile.component.ts.ClientProfileComp.delete
(clientProfile.component.ts:53)... (etc).
我已使用 postman 确认我的快速路由按预期工作。我能够在 /api/clients
获得 all/create 个客户,以及从 /api/clients/:_id
获得、放置和删除(其中 _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: any;
替换了 clientProfile: ClientProfile;
的所有实例)
注意注释掉的导入语句。
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; }
});
}
}
我整天都在研究这个问题,并且在这里也阅读了很多类似的 posts - 但大多数解决方案似乎并不适用于这种情况。如果有人能指出我正确的方向,我将不胜感激。如果需要更多代码来解释我正在尝试做的事情,我会很乐意 post 它。
根据错误信息看来错误出在这里:
this.router.navigate(['/detail', this.selectedClientProfile._id])
您似乎只在 onSelect
中设置了它,并且您的代码中有几个地方将 this.selectedClientProfile
设置为 null。那将是最好看的地方。
如果您想创建一个 plunker 来演示您的问题,我们可以进一步研究它。
附带说明一下,您正在使用 promises 而不是现在更常见的 Observables。如果你想改用 Observables,我在这里有一个完整的 CRUD(创建、读取、更新和删除)操作示例:https://github.com/DeborahK/Angular2-ReactiveForms 在 APM 文件夹中。
发现一个问题 - 我在 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>
我是第一次构建应用程序来存储、更新、查看和删除客户资料。我按照 Angular 英雄之旅构建了基本应用程序,然后拼凑了 mongodb 并表达了来自网络的部分内容。
当我尝试删除客户端配置文件时,我的浏览器控制台出现此错误 -
ERROR TypeError: Cannot read property '_id' of undefined at ClientProfileComp.webpackJsonp.../../../../../src/app/components/clientProfile.component.ts.ClientProfileComp.delete (clientProfile.component.ts:53)... (etc).
我已使用 postman 确认我的快速路由按预期工作。我能够在 /api/clients
获得 all/create 个客户,以及从 /api/clients/:_id
获得、放置和删除(其中 _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: any;
替换了 clientProfile: ClientProfile;
的所有实例)
注意注释掉的导入语句。
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; }
});
}
}
我整天都在研究这个问题,并且在这里也阅读了很多类似的 posts - 但大多数解决方案似乎并不适用于这种情况。如果有人能指出我正确的方向,我将不胜感激。如果需要更多代码来解释我正在尝试做的事情,我会很乐意 post 它。
根据错误信息看来错误出在这里:
this.router.navigate(['/detail', this.selectedClientProfile._id])
您似乎只在 onSelect
中设置了它,并且您的代码中有几个地方将 this.selectedClientProfile
设置为 null。那将是最好看的地方。
如果您想创建一个 plunker 来演示您的问题,我们可以进一步研究它。
附带说明一下,您正在使用 promises 而不是现在更常见的 Observables。如果你想改用 Observables,我在这里有一个完整的 CRUD(创建、读取、更新和删除)操作示例:https://github.com/DeborahK/Angular2-ReactiveForms 在 APM 文件夹中。
发现一个问题 - 我在 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>