问题
I'm trying to format a date field in my ionic project. THis date field is being read in from Firebase and I try to format it in the html page but I'm getting the following error: TypeError: Cannot read property 'seconds' of undefined
The strange thing is that it displays as I would expect on screen but I'm not sure why the console error is displayed
Attaching the .html, related .ts and .service.ts
Here is the html code: (note that removing the format section I do not get the error)
<ion-item>
<ion-label>
DOB: <font>{{currentPlayerDetails?.dateOfBirth.seconds * 1000 |
date:'d/MMM/yyyy' }}</font>
</ion-label>
</ion-item>
A snippet of the related .ts file
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;
});
}
}
And finally some of the .service.ts file
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);
}
}
Output of the console.log of this.currentPlayerDetails
{
"country": "UK",
"county": "Warwickshire",
"dateOfBirth": {
"seconds": 527986800,
"nanoseconds": 0
},
"firstName": "Kevin",
"photoLocation": "",
"position": "Midfield",
"surname": "Browne",
"team": "Mens",
"town": "Birmingham",
"id": "HVbUmm1KwKjy9fwtsCdP"
}
回答1:
You should use Async/Await functions when dealing with firebase calls since almost everything is asynchronous, this is why it probably doesn´t have any value to format at that moment.
Try reading this post and maybe it will help you.
回答2:
As the error is clearly saying, the dateOfBirth
is undefined and that's why it can't find property seconds
of undefined. I would suggest try console priting of currentPlayerDetails
and see what data you are getting from firebase.
Also I see its returning a promise, please use async/await to make sure that is available when ngOnInit completes. This blog is good reference to understand how promise works.
UPDATE: EXPLAINATION
You are binding listener/subscriber
inside ngOnInit
to firebase
call which returns a promise
, and inside the subscriber
you are updating the value of class property currentPlayerDetails
which you have bound to the angular view. So when your page loads/inits angular completes its NgOnInit
lifecycle hooks to bound subscriber to firebase promise
but its not haulting the page load event until the promise
resolves (i.e. the data is fetch), but it does eventually resolves and updates the currentPlayerDetails
class property.
This all happens within fraction of seconds, you can't barely notice the UI changes in the view. And that's why you see the error in console(this is when promise is not yet resolved but page load event is occuring) but the UI displays the data (at this point everything is loaded & promise is resolved as well), since the process is asynchronous
.
The right way to consume a promise synchronously through use of async/await
, this will get rid of your console error:
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;
}
}
来源:https://stackoverflow.com/questions/56671882/error-typeerror-cannot-read-property-seconds-of-undefined-when-trying-to-f