ОШИБКА TypeError: Невозможно прочитать свойство 'непрочитанное' из неопределенного

Я получаю сообщение об ошибке ниже, когда страница загружается впервые, но я могу просто выйти из нее, и все продолжает работать, как и ожидалось.

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.

Когда я запускаю приведенный ниже код, все работает, как ожидалось, но я не могу избавиться от Cannot read property 'unread' ошибка, которая выскакивает в init независимо от того, в скольких операторах if я обертываю битую часть кода. Это как будто у меня есть Schrodinger's 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 ответа

Решение

Проверьте, существует ли поток для пользователя, прежде чем пытаться получить доступ к непрочитанному свойству. Пожалуйста, дайте мне знать, если вы все еще сталкиваетесь с этой проблемой

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

return { id, ...data } объединит идентификатор и все поля данных в одно.

теперь ваш 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;
        }
      })
    })

Вы можете попробовать, как показано ниже.

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;
                }
              })
            })
          })
        }
      });
Другие вопросы по тегам