我有一个补丁请求,看起来像这样:
patchSharingStatus(id: string): Observable<Idea> {
return this.http.patch<Idea>(this.ideaApiUrl + '/' + id + '/sharing', {});
}它命中我的API,我的API返回一个包含两个字段的对象,一个名为sharingEnabled,另一个名为sharingLink。
我在这里使用patchSharingStatus():
toggleSharing(id: string) {
this.bigIdeaService.patchSharingStatus(id).subscribe(res => {
const oldItemIndex = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;
console.log('oldItemIndex', oldItemIndex);
console.log('oldItem', this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId));
console.log('res.sharingEnabled', res.sharingEnabled);
console.log('res.sharingLink', res.sharingLink);
// The below line is (view.page.ts:81) from the below stack trace.
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled; // <== This is (view.page.ts:81) from the below stack trace.
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingLink = res.sharingLink;
});
}在我的浏览器控制台中,我看到了以下内容:
oldItemIndex 58832ca4-ef93-4aa5-a670-83dc4384c306
instrument.ts:129 oldItem {sharingEnabled: true
sharingLink: "http://localhost:8100/sharing/item/df5a3bb0-8c46-4c4c-a70a-37a3465fe62b" ...}
instrument.ts:129 res.sharingEnabled true
instrument.ts:129 res.sharingLink http://localhost:8100/sharing/item/65a27b76-b65f-4dfe-b013-0b1a9c8254db
instrument.ts:129 TypeError: Cannot set property 'sharingEnabled' of undefined
at SafeSubscriber._next (view.page.ts:81)
at SafeSubscriber.__tryOrUnsub (Subscriber.ts:265)
at SafeSubscriber.next (Subscriber.ts:207)
at Subscriber._next (Subscriber.ts:139)
at Subscriber.next (Subscriber.ts:99)
at MapSubscriber._next (map.ts:89)
at MapSubscriber.next (Subscriber.ts:99)
at FilterSubscriber._next (filter.ts:101)
at FilterSubscriber.next (Subscriber.ts:99)
at MergeMapSubscriber.notifyNext (mergeMap.ts:162)
at SimpleInnerSubscriber._next (innerSubscribe.ts:30)
at SimpleInnerSubscriber.next (Subscriber.ts:99)
at CatchSubscriber._next (Subscriber.ts:139)
at CatchSubscriber.next (Subscriber.ts:99)
at MergeMapSubscriber.notifyNext (mergeMap.ts:162)
at SimpleInnerSubscriber._next (innerSubscribe.ts:30)
at SimpleInnerSubscriber.next (Subscriber.ts:99)
at XMLHttpRequest.onLoad (xhr.ts:215)
at XMLHttpRequest.sentryWrapped (helpers.ts:87)
at ZoneDelegate.invokeTask (zone.js:429)
at Object.onInvokeTask (core.js:28500)
at ZoneDelegate.invokeTask (zone.js:428)
at Zone.runTask (zone.js:200)
at ZoneTask.invokeTask [as invoke] (zone.js:511)
at invokeTask (zone.js:1651)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1688)这个错误会告诉我上面打印的响应数据不包含名为sharingEnabled的字段,或者它可能包含,但它是空的。事实并非如此。我已经检查了来自API的响应,它很好,我可以在上面看到这些值被正确填充。
我甚至可以在我的前端看到返回的数据正在显示!
怎么回事?这是一个令人讨厌的错误,我想摆脱它。有人能帮上忙吗?
编辑:
为了在这里添加更多上下文,我有一个呈现数据的angular组件。为数组中的每个项目创建一个组件(它是一个想法列表)。这些组件中的每一个都有一个从父页面传入的想法。每个组件都有一个发射器,该发射器在组件的父页面中触发一个方法-这就是方法调用patchSharingStatus()。
toggleSharing()也在父级中。this.activeProjectAndAssessmentDetails也在父级中,这是驱动所有组件的阵列。toggleSharing()从API获取响应,并修改响应所涉及的项,然后我依赖于该更改使子组件重新呈现(React做了类似的事情-这是它的工作方式吗?)
编辑2:根据Nicholas_Jones,我添加了一条if语句来检查oldItemIndex是否为空。
这是toggleSharing的更新版本
toggleSharing(id: string) {
this.bigIdeaService.patchSharingStatus(id).subscribe(res => {
const oldItemIndex = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;
console.log('oldItemIndex', oldItemIndex);
console.log('res.bigIdeaId', res.bigIdeaId);
if (!this.activeProjectAndAssessmentDetails[oldItemIndex]) { console.log('im undefined'); }
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingLink = res.sharingLink;
});
}和新的堆栈跟踪:
oldItemIndex 9360d92d-e04c-4069-872d-dca880d9f1eb
instrument.ts:129 res.bigIdeaId 9360d92d-e04c-4069-872d-dca880d9f1eb
instrument.ts:129 im undefined
instrument.ts:129 TypeError: Cannot set property 'sharingEnabled' of undefined
at SafeSubscriber._next (view.page.ts:82)
at SafeSubscriber.__tryOrUnsub (Subscriber.ts:265)
at SafeSubscriber.next (Subscriber.ts:207)
at Subscriber._next (Subscriber.ts:139)
at Subscriber.next (Subscriber.ts:99)
at MapSubscriber._next (map.ts:89)
at MapSubscriber.next (Subscriber.ts:99)
at FilterSubscriber._next (filter.ts:101)
at FilterSubscriber.next (Subscriber.ts:99)
at MergeMapSubscriber.notifyNext (mergeMap.ts:162)
at SimpleInnerSubscriber._next (innerSubscribe.ts:30)
at SimpleInnerSubscriber.next (Subscriber.ts:99)
at CatchSubscriber._next (Subscriber.ts:139)
at CatchSubscriber.next (Subscriber.ts:99)
at MergeMapSubscriber.notifyNext (mergeMap.ts:162)
at SimpleInnerSubscriber._next (innerSubscribe.ts:30)
at SimpleInnerSubscriber.next (Subscriber.ts:99)
at XMLHttpRequest.onLoad (xhr.ts:215)
at XMLHttpRequest.sentryWrapped (helpers.ts:87)
at ZoneDelegate.invokeTask (zone.js:429)
at Object.onInvokeTask (core.js:28500)
at ZoneDelegate.invokeTask (zone.js:428)
at Zone.runTask (zone.js:200)
at ZoneTask.invokeTask [as invoke] (zone.js:511)
at invokeTask (zone.js:1651)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1688)不幸的是,null检查被触发了,但是在我打印了oldItemIndex并看到有一个值之后才打印出来!
所以这可能是某种竞争条件?
发布于 2021-02-09 03:01:14
如何解决像这样的问题...
toggleSharing(id: string) {
this.bigIdeaService.patchSharingStatus(id).subscribe(res => {
const oldItemIndex = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;
console.log('oldItemIndex', oldItemIndex);
console.log('oldItem', this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId));
console.log('res.sharingEnabled', res.sharingEnabled);
console.log('res.sharingLink', res.sharingLink);
// The below line is (view.page.ts:81) from the below stack trace.
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled; // <== This is (view.page.ts:81) from the below stack trace.
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingLink = res.sharingLink;
});
}
Error:
instrument.ts:129 TypeError: Cannot set property 'sharingEnabled' of undefined
...这个错误说明解释器不能运行这行代码
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;如果你要注释这一行,那么下面这一行也会出现同样的错误。
我很惊讶你没有收到某种形式的Typescript警告,通常它应该显示一个“可能未定义”的警告。
添加一些额外的逻辑来帮助检测对象是否未定义,如下所示
if (this.activeProjectAndAssessmentDetails[oldItemIndex]) {
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingLink = res.sharingLink;
}或
this.activeProjectAndAssessmentDetails[oldItemIndex]?.sharingEnabled = res.sharingEnabled;
this.activeProjectAndAssessmentDetails[oldItemIndex]?.sharingLink = res.sharingLink;如果这些线路未运行,则执行下一个故障排除步骤,检查并修复oldItemIndex。
因为你的数据可能有多种结构,我不能给出你问题中的信息,但是,如果你的数据结构如下,并且你正在访问对象属性/键,那么代码可能是正确的。
activeProjectAndAssessmentDetails = {
58832ca4-ef93-4aa5-a670-83dc4384c306: {
sharingEnabled: "someValue",
sharingLink: "someValue"
...etc
},
58832ca4-ef93-4aa5-a670-83dc4384c307: {
sharingEnabled: "someValue2",
sharingLink: "someValue2"
...etc
},
}代码
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;然后访问属性/键,但我假设这不是您的数据的结构。
我假设你的数据结构更像这样...
activeProjectAndAssessmentDetails = [
0: {
sharingEnabled: "someValue",
sharingLink: "someValue"
...etc
},
1: {
sharingEnabled: "someValue2",
sharingLink: "someValue2"
...etc
},
]这意味着您正在尝试使用字符串UID访问基于数字的索引。这可能会返回由于索引不正确而未定义的对象。
在看到您的反馈后,事实就是如此,通过使用Array.Prototype.find()方法从UID值切换到包含匹配UID的对象的索引,解决了您的问题。
const oldItemId = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;
const oldItemIndex = this.activeProjectAndAssessmentDetails.indexOf(this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId));发布于 2021-02-08 13:44:15
Nicholas_Jones如果你把这个答案贴出来,我会把它归功于你。
我意识到我有一个逻辑错误。
const oldItemId = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;
const oldItemIndex = this.activeProjectAndAssessmentDetails.indexOf(this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId));之前,我指的是oldItemId --如上所述,它是一个字符串UUID。然后,我尝试在该id的索引处记录该项目-这没有任何意义,因此array.prototype.find()没有找到任何您所期望的东西。
我更改了对oldItemIndex的引用,如上所述- thick获取array.prototype.find()找到的项,然后获取它的索引。
谢谢你的帮助!
发布于 2021-02-08 12:15:38
你可以让console.log(this.activeProjectAndAssessmentDetailsoldItemIndex)只是为了确保数据,并将堆栈跟踪发送给我。也是this.activeProjectAndAssessmentDetails.length和oldItemIndex的console.log
https://stackoverflow.com/questions/66095739
复制相似问题