错误类型错误:无法读取未定义的属性“未读”

Posted

技术标签:

【中文标题】错误类型错误:无法读取未定义的属性“未读”【英文标题】:ERROR TypeError: Cannot read property 'unread' of undefined 【发布时间】:2018-04-29 11:22:52 【问题描述】:

当页面首次加载时,我不断收到下面的错误,但我可以退出它,一切都按预期工作。

ERROR TypeError: Cannot read property 'unread' 
of undefined
at listing-element.ts:34
at Array.forEach (<anonymous>)
at SafeSubscriber._next (listing-element.ts:33)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:238)
at SafeSubscriber.next (Subscriber.js:185)
at Subscriber._next (Subscriber.js:125)
at Subscriber.next (Subscriber.js:89)
at MapSubscriber._next (map.js:83)
at MapSubscriber.Subscriber.next (Subscriber.js:89)
at MapSubscriber._next (map.js:83)

我目前正在使用 Angular 4.4.3、Ionic-Angular 3.9.2、AngularFire2 5.0.0。

当我运行下面的代码时,一切都按预期工作,但我似乎无法摆脱在 init 上弹出的 Cannot read property 'unread' 错误,无论我将有问题的代码包含多少 if 语句。就像我有薛定谔的 Observable;我同时得到了我期望的数据,但它回来了未定义。我意识到这是由于 Observables 的异步特性造成的,但在我的团队将我们的数据库切换到 Google Firestore 并因此不得不升级 AngularFire 2 之前,我对此没有任何问题。

我们的管道和 html 也存在类似问题。对于我们的 HTML,通常将代码包装在 &lt;div *ngIf="thread"&gt; 中会起作用,这样它只会在我们获得列表数据时出现。但是,将 TypeScript 包装在 if (threads.length &gt; 0 &amp;&amp; threads) 之类的内容中没有任何作用,因为数据仍会在控制台记录预期的结果。

    //listing-element.ts
    this.userId = this.auth.getUser().uid;
    this.listingProvider.checkUnreadThreads(this.listing.id).subscribe(threads => 
          threads.forEach(thread => 
            if (thread[this.userId].unread)  // <-Line 34 is here
              this.unread = true;
            
          )
        )

    //listing-provider
      checkUnreadThreads(listingId) 
        return this.afs.collection(`listings/$listingId/threads`)
          .snapshotChanges()
          .map(actions => 
            return actions.map(action => 
              const id = action.payload.doc.id;
              const data = action.payload.doc.data();
              return  id, ...data 
            );
          )
      

    //listing-element.html
    <notification-badge *ngIf="userId === listingUserId && page.activity === true && unread"></notification-badge>

这是我认为相关的所有信息,但如果有人需要更多信息,我非常乐意提供我能提供的任何信息。

【问题讨论】:

【参考方案1】:

在尝试访问 unthread 属性之前检查用户是否存在线程。如果您仍然遇到这个问题,请告诉我

if (thread[this.userId] && thread[this.userId].unread)  
              this.unread = true;
            

【讨论】:

谢谢,虽然示例本身不起作用,但它确实给了我尝试将其包装在另一个 if 语句中的想法,但只有 thread[this.userId] 作为条件,而不是 thread[this.userId].unread,它停止给我错误! 很高兴它有帮助:)【参考方案2】:

您可以尝试如下所示。

this.afAuth.authState.subscribe(
      (auth) => 
        if (auth != null) 
            this.listingProvider.checkUnreadThreads(this.listing.id).subscribe(threads 
               => 
              threads.forEach(thread => 
                if (thread[auth.uid].unread)  // <-Line 34 is here
                  this.unread = true;
                
              )
            )
          )
        
      );

【讨论】:

【参考方案3】:

return id, ...data 会将 id 和所有数据字段合并为一个。

现在你的thread 看起来像这样

id:....,
unread:....,
fieldx:....,
fieldy:..... etc

试试这个代码

this.userId = this.auth.getUser().uid;
this.listingProvider.checkUnreadThreads(this.listing.id).subscribe(threads => 
      threads.forEach(thread => 
        if (thread.id == this.userId && thread.unread)  
          this.unread = true;
        
      )
    )

【讨论】:

以上是关于错误类型错误:无法读取未定义的属性“未读”的主要内容,如果未能解决你的问题,请参考以下文章

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`

未捕获的类型错误:无法读取未定义的属性“区域”?

未捕获的类型错误:无法读取未定义的属性 toLowerCase

JQuery:未捕获的类型错误:无法读取未定义的属性“调用”

未捕获的类型错误:无法读取文本字段上未定义错误的属性“toLowerCase”

NextJS:未捕获的类型错误:无法读取未定义的属性(读取“属性”)