首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >返回的TS observable未定义,除非未定义

返回的TS observable未定义,除非未定义
EN

Stack Overflow用户
提问于 2021-02-08 11:58:21
回答 3查看 38关注 0票数 0

我有一个补丁请求,看起来像这样:

代码语言:javascript
运行
复制
patchSharingStatus(id: string): Observable<Idea> {
        return this.http.patch<Idea>(this.ideaApiUrl + '/' + id + '/sharing', {});
    }

它命中我的API,我的API返回一个包含两个字段的对象,一个名为sharingEnabled,另一个名为sharingLink

我在这里使用patchSharingStatus()

代码语言:javascript
运行
复制
    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;
            });
        }

在我的浏览器控制台中,我看到了以下内容:

代码语言:javascript
运行
复制
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的更新版本

代码语言:javascript
运行
复制
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;
        });
    }

和新的堆栈跟踪:

代码语言:javascript
运行
复制
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并看到有一个值之后才打印出来!

所以这可能是某种竞争条件?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-02-09 03:01:14

如何解决像这样的问题...

代码语言:javascript
运行
复制
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
...

这个错误说明解释器不能运行这行代码

代码语言:javascript
运行
复制
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;

如果你要注释这一行,那么下面这一行也会出现同样的错误。

我很惊讶你没有收到某种形式的Typescript警告,通常它应该显示一个“可能未定义”的警告。

添加一些额外的逻辑来帮助检测对象是否未定义,如下所示

代码语言:javascript
运行
复制
if (this.activeProjectAndAssessmentDetails[oldItemIndex]) {
  this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled; 
  this.activeProjectAndAssessmentDetails[oldItemIndex].sharingLink = res.sharingLink;
}

代码语言:javascript
运行
复制
this.activeProjectAndAssessmentDetails[oldItemIndex]?.sharingEnabled = res.sharingEnabled; 
this.activeProjectAndAssessmentDetails[oldItemIndex]?.sharingLink = res.sharingLink;

如果这些线路未运行,则执行下一个故障排除步骤,检查并修复oldItemIndex。

因为你的数据可能有多种结构,我不能给出你问题中的信息,但是,如果你的数据结构如下,并且你正在访问对象属性/键,那么代码可能是正确的。

代码语言:javascript
运行
复制
activeProjectAndAssessmentDetails = {
  58832ca4-ef93-4aa5-a670-83dc4384c306: {
    sharingEnabled: "someValue",
    sharingLink: "someValue"
    ...etc
  },
  58832ca4-ef93-4aa5-a670-83dc4384c307: {
    sharingEnabled: "someValue2",
    sharingLink: "someValue2"
    ...etc
  },


}

代码

代码语言:javascript
运行
复制
this.activeProjectAndAssessmentDetails[oldItemIndex].sharingEnabled = res.sharingEnabled;

然后访问属性/键,但我假设这不是您的数据的结构。

我假设你的数据结构更像这样...

代码语言:javascript
运行
复制
activeProjectAndAssessmentDetails = [
  0: {
    sharingEnabled: "someValue",
    sharingLink: "someValue"
    ...etc
  },
  1: {
    sharingEnabled: "someValue2",
    sharingLink: "someValue2"
    ...etc
  },
]

这意味着您正在尝试使用字符串UID访问基于数字的索引。这可能会返回由于索引不正确而未定义的对象。

在看到您的反馈后,事实就是如此,通过使用Array.Prototype.find()方法从UID值切换到包含匹配UID的对象的索引,解决了您的问题。

代码语言:javascript
运行
复制
const oldItemId = this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId).parentIdeaId;

const oldItemIndex = this.activeProjectAndAssessmentDetails.indexOf(this.activeProjectAndAssessmentDetails.find(item => item.parentIdeaId === res.bigIdeaId));
票数 1
EN

Stack Overflow用户

发布于 2021-02-08 13:44:15

Nicholas_Jones如果你把这个答案贴出来,我会把它归功于你。

我意识到我有一个逻辑错误。

代码语言:javascript
运行
复制
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()找到的项,然后获取它的索引。

谢谢你的帮助!

票数 2
EN

Stack Overflow用户

发布于 2021-02-08 12:15:38

你可以让console.log(this.activeProjectAndAssessmentDetailsoldItemIndex)只是为了确保数据,并将堆栈跟踪发送给我。也是this.activeProjectAndAssessmentDetails.length和oldItemIndex的console.log

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66095739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档