core.js:6406 ERROR TypeError: Cannot read property 'id' of undefined
core.js:6406 ERROR TypeError: Cannot read property 'id' of undefined
我有一个 angular 8 应用程序。和一个创建功能。但是我不能创建一个项目,因为id是空的。
我当然用谷歌搜索了这个。但我认为这是一个具体案例。
这是将触发函数的模板:
<button *ngIf="isNew" mat-raised-button color="primary" [appSubmitIfValid]="editItemForm" (valid)="save()" i18n>Create</button>
这是实际功能:
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.dossierItems.unshift(item);
this.sortDossierItems();
this.isNew = false;
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
这是我的 router.ts:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
所以我在这一行得到一个错误:
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
id
是 null
。
但是我必须改变什么?
谢谢
更新:
这是用于添加新项目的 link:view.component.html:
<ng-template mat-tab-label #interviews>
<mat-icon class="interviews">speaker_notes</mat-icon>
<span i18n>Interview reports</span>{{ dossierItemsCountString(itemTypes.Interview) }}
<a [routerLink]="['../' , dossier.id , 'item' , 'new', itemTypes.Interview]">
<mat-icon class="add_box">add</mat-icon>
</a>
</ng-template>
问题出在路由上。因为如果我这样做:
{
path: ':dossierId/item/new/:dossierItemType', component: ItemComponent,
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
然后我可以创建一个新项目。但这不是我想要的,因为新项目将在新视图中加载。
这就是为什么我有这个:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
但是每次档案都是空的。
已满item.component.ts代码:
export class ItemComponent implements OnInit {
itemTypes = DossierItemTypeDto;
formBuilder = new FormBuilder();
isNew = false;
editItemForm: FormGroup;
dossierItemId: string;
item: DossierItemDto;
dossierItems: DossierItemDto[];
dossier: DossierDto;
globalErrors: ValidationErrors;
constructor(private dossierService: DossierService, private route: ActivatedRoute, private router: Router,
private errorProcessor: ErrorProcessor) {
this.dossier = this.route.snapshot.data.dossier;
this.dossierItemId = this.route.snapshot.params.dossierItemId;
this.isNew = this.dossierItemId === undefined;
this.dossierItems = this.route.snapshot.data.dossierItems;
if (this.isNew) {
this.item = {
title: '',
itemType: this.route.snapshot.params.dossierItemType,
date: moment().format('Y-MM-DD'),
createdAt: moment().format('Y-MM-DD'),
body: '' };
} else {
this.item = this.dossierItems.find(i => i.id === this.dossierItemId);
}
}
ngOnInit(): void {
this.editItemForm = this.formBuilder.group({
title: this.formBuilder.control(this.item.title, [Validators.required]),
itemType: this.formBuilder.control(this.item.itemType, [Validators.required]),
date: this.formBuilder.control(moment(this.item.date, 'Y-MM-DD'), [Validators.required]),
body: this.formBuilder.control(this.item.body, [Validators.required, Validators.maxLength(2097152)])
});
}
save(): void {
const form = this.editItemForm;
const dossierItemDto: DossierItemPostDto = {
title: form.controls.title.value,
itemType: form.controls.itemType.value,
date: (form.controls.date.value as moment.Moment).format('Y-MM-DD'),
body: form.controls.body.value
};
form.disable();
if (!this.isNew) {
this.dossierService.updateDossierItemById(this.dossier.id, this.item.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.sortDossierItems();
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
} else {
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.dossierItems.unshift(item);
this.sortDossierItems();
this.isNew = false;
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
}
}
}
但如果我尝试这样做:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
好的,这很奇怪,因为在此:
ngOnInit(): void {
this.route.params.subscribe((params: Params) => {
this.dossier.id = params.dossierId;
});
在调试器中。我第一次看到设置了id:
"06637e72-8915-4735-9400-4ef7705194ea"
但如果我执行 f8 则 id 为空:
this.dossier.id = params.dossierId;
我的路线是这样的:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
所以调用了两次:
this.route.params.subscribe((params: Params) => {
this.dossier.id = params.dossierId;
});
不明白为什么
你可以试试 paramsInheritanceStrategy
吗?
@NgModule({
imports: [RouterModule.forRoot(routes,{
paramsInheritanceStrategy: 'always'
})],
exports: [RouterModule]
})
export class AppRoutingModule { }
您还需要捕获父路由参数
下面的代码对我有用:
在你的 tsconfig.json 个项目中 Angular
{
...
"angularCompilerOptions": {
"enableIvy": false
}
}
尝试使用 elvis 运算符? .假设您想访问 object.id try object?.id。通常,当您尝试访问可能可为空的数据或其引用可能丢失时,就会发生这种情况
我有一个 angular 8 应用程序。和一个创建功能。但是我不能创建一个项目,因为id是空的。
我当然用谷歌搜索了这个。但我认为这是一个具体案例。
这是将触发函数的模板:
<button *ngIf="isNew" mat-raised-button color="primary" [appSubmitIfValid]="editItemForm" (valid)="save()" i18n>Create</button>
这是实际功能:
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.dossierItems.unshift(item);
this.sortDossierItems();
this.isNew = false;
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
这是我的 router.ts:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
所以我在这一行得到一个错误:
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
id
是 null
。
但是我必须改变什么?
谢谢
更新:
这是用于添加新项目的 link:view.component.html:
<ng-template mat-tab-label #interviews>
<mat-icon class="interviews">speaker_notes</mat-icon>
<span i18n>Interview reports</span>{{ dossierItemsCountString(itemTypes.Interview) }}
<a [routerLink]="['../' , dossier.id , 'item' , 'new', itemTypes.Interview]">
<mat-icon class="add_box">add</mat-icon>
</a>
</ng-template>
问题出在路由上。因为如果我这样做:
{
path: ':dossierId/item/new/:dossierItemType', component: ItemComponent,
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
然后我可以创建一个新项目。但这不是我想要的,因为新项目将在新视图中加载。
这就是为什么我有这个:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
但是每次档案都是空的。
已满item.component.ts代码:
export class ItemComponent implements OnInit {
itemTypes = DossierItemTypeDto;
formBuilder = new FormBuilder();
isNew = false;
editItemForm: FormGroup;
dossierItemId: string;
item: DossierItemDto;
dossierItems: DossierItemDto[];
dossier: DossierDto;
globalErrors: ValidationErrors;
constructor(private dossierService: DossierService, private route: ActivatedRoute, private router: Router,
private errorProcessor: ErrorProcessor) {
this.dossier = this.route.snapshot.data.dossier;
this.dossierItemId = this.route.snapshot.params.dossierItemId;
this.isNew = this.dossierItemId === undefined;
this.dossierItems = this.route.snapshot.data.dossierItems;
if (this.isNew) {
this.item = {
title: '',
itemType: this.route.snapshot.params.dossierItemType,
date: moment().format('Y-MM-DD'),
createdAt: moment().format('Y-MM-DD'),
body: '' };
} else {
this.item = this.dossierItems.find(i => i.id === this.dossierItemId);
}
}
ngOnInit(): void {
this.editItemForm = this.formBuilder.group({
title: this.formBuilder.control(this.item.title, [Validators.required]),
itemType: this.formBuilder.control(this.item.itemType, [Validators.required]),
date: this.formBuilder.control(moment(this.item.date, 'Y-MM-DD'), [Validators.required]),
body: this.formBuilder.control(this.item.body, [Validators.required, Validators.maxLength(2097152)])
});
}
save(): void {
const form = this.editItemForm;
const dossierItemDto: DossierItemPostDto = {
title: form.controls.title.value,
itemType: form.controls.itemType.value,
date: (form.controls.date.value as moment.Moment).format('Y-MM-DD'),
body: form.controls.body.value
};
form.disable();
if (!this.isNew) {
this.dossierService.updateDossierItemById(this.dossier.id, this.item.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.sortDossierItems();
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
} else {
this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
.subscribe(item => {
this.item = item;
this.dossierItems.unshift(item);
this.sortDossierItems();
this.isNew = false;
form.enable();
form.markAsPristine();
this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
}, error => this.handleError(error));
}
}
}
但如果我尝试这样做:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
好的,这很奇怪,因为在此:
ngOnInit(): void {
this.route.params.subscribe((params: Params) => {
this.dossier.id = params.dossierId;
});
在调试器中。我第一次看到设置了id:
"06637e72-8915-4735-9400-4ef7705194ea"
但如果我执行 f8 则 id 为空:
this.dossier.id = params.dossierId;
我的路线是这样的:
{
path: ':dossierId',
component: ViewComponent, children: [
{ path: 'item/new/:dossierItemType', component: ItemComponent}
],
resolve: {
dossier: DossierResolver,
dossierItems: DossierItemsResolver
}
},
所以调用了两次:
this.route.params.subscribe((params: Params) => {
this.dossier.id = params.dossierId;
});
不明白为什么
你可以试试 paramsInheritanceStrategy
吗?
@NgModule({
imports: [RouterModule.forRoot(routes,{
paramsInheritanceStrategy: 'always'
})],
exports: [RouterModule]
})
export class AppRoutingModule { }
您还需要捕获父路由参数
下面的代码对我有用:
在你的 tsconfig.json 个项目中 Angular
{
...
"angularCompilerOptions": {
"enableIvy": false
}
}
尝试使用 elvis 运算符? .假设您想访问 object.id try object?.id。通常,当您尝试访问可能可为空的数据或其引用可能丢失时,就会发生这种情况