Ошибка: «Ошибка типа: не удается прочитать свойство« секунды »неопределенного» при попытке отформатировать поле даты - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь отформатировать поле даты в моем ионном проекте. Это поле даты читается из Firebase, и я пытаюсь отформатировать его на html-странице, но получаю следующую ошибку: TypeError: Невозможно прочитать свойство 'seconds' из неопределенного

Странно то, что он отображается так, как я ожидал на экране, но я не уверен, почему отображается ошибка консоли

Присоединение .html, связанных .ts и .service.ts

Вот HTML-код: (обратите внимание, что при удалении раздела формата я не получаю сообщение об ошибке)

   <ion-item>
       <ion-label>
           DOB: <font>{{currentPlayerDetails?.dateOfBirth.seconds * 1000 | 
                       date:'d/MMM/yyyy' }}</font>
       </ion-label>
    </ion-item>

Фрагмент связанного файла .ts

 export class PlayerDetailsPage implements OnInit {

   public currentPlayerDetails: any = {};

      constructor(private playersService: PlayersService,private 
 helperService: HelperService, 
                private route: ActivatedRoute) { }

   ngOnInit() {
      const playerId: string = this.route.snapshot.paramMap.get('id');
       this.playersService.getPlayerDetails(playerId).get()
       .then(playerDetailsSnapshot=> {
          this.currentPlayerDetails = playerDetailsSnapshot.data();
          this.currentPlayerDetails.id = playerDetailsSnapshot.id;

       });
  }
 }

И, наконец, некоторые из файлов .service.ts

export class PlayersService {

 public playersRef: firebase.firestore.CollectionReference;

   constructor() { 
     this.playersRef = firebase.firestore().collection('/players');   
  }


     getPlayerDetails(playerDetailsId: string): 
    firebase.firestore.DocumentReference {
               return this.playersRef.doc(playerDetailsId);        
         }
 }

Вывод файла console.log файла this.currentPlayerDetails

{
  "country": "UK",
  "county": "Warwickshire",
  "dateOfBirth": {
    "seconds": 527986800,
    "nanoseconds": 0
  },
  "firstName": "Kevin",
  "photoLocation": "",
  "position": "Midfield",
  "surname": "Browne",
  "team": "Mens",
  "town": "Birmingham",
  "id": "HVbUmm1KwKjy9fwtsCdP"
}

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

Вы должны использовать функции Async / Await при работе с вызовами firebase, так как почти все асинхронно, поэтому, вероятно, у него нет значения для форматирования в этот момент.

Попробуйте прочитать this пост и возможно он вам поможет.

0 голосов
/ 19 июня 2019

Как ясно говорит об ошибке, dateOfBirth не определено, и поэтому он не может найти свойство seconds не определено.Я бы посоветовал попробовать консольную печать currentPlayerDetails и посмотреть, какие данные вы получаете от firebase.

Также я вижу, что он возвращает обещание, пожалуйста, используйте async / await, чтобы убедиться, что он доступен после завершения ngOnInit.Этот блог является хорошим справочным материалом, чтобы понять, как работает обещание.

ОБНОВЛЕНИЕ: ОБЪЯСНЕНИЕ

Вы связываете listener/subscriber внутри ngOnInit с *Вызов 1016 *, который возвращает promise, а внутри subscriber вы обновляете значение свойства класса currentPlayerDetails, которое вы привязали к угловому виду.Таким образом, когда ваша страница загружается / inits angular завершает свои NgOnInit перехваты жизненного цикла для привязки подписчика к firebase promise, но это не вызывает событие загрузки страницы до тех пор, пока promise не разрешит (то есть данные извлекаются), но это в конечном итоге разрешается иобновляет свойство класса currentPlayerDetails.

Все это происходит за доли секунды, вы не можете просто заметить изменения пользовательского интерфейса в представлении.И именно поэтому вы видите ошибку в консоли (это когда обещание еще не разрешено, но происходит событие загрузки страницы), но пользовательский интерфейс отображает данные (в этот момент все загружается и обещание также разрешается), так как процессasynchronous.

Правильный способ синхронного получения обещания с использованием async/await, это избавит вас от ошибки консоли:

export class PlayerDetailsPage implements OnInit {

    public currentPlayerDetails: any = {};

    constructor(private playersService: PlayersService,
        private helperService: HelperService,
        private route: ActivatedRoute) { }

    ngOnInit() {
        this.fetchPlayerDetails(this.route.snapshot.paramMap.get('id'));
    }

    private async fetchPlayerDetails(playerId: string) {
        const playerDetailsSnapshot = await this.playersService.getPlayerDetails(playerId).get();
        this.currentPlayerDetails = playerDetailsSnapshot.data();
        this.currentPlayerDetails.id = playerDetailsSnapshot.id;
    }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...