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

时间:2017-11-16 03:05:55

标签: angular typescript observable ionic3 angularfire2

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

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,通常将代码包装在<div *ngIf="thread">中将起作用,因此只有在我们获取列表数据后才会显示。但是,将TypeScript包装在if (threads.length > 0 && 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>

这是我认为相关的所有信息,但如果有人需要更多信息,我很乐意尽我所能。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您可以尝试如下所示。

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;
                }
              })
            })
          })
        }
      });

答案 2 :(得分:0)

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;
        }
      })
    })