Reputation: 195
I'm trying to use the toDate()
function to convert a timestamp into a readable date using the toDate()
from firestore
and moment.js
to convert to the desired date format.
It all looks good until I use the toDate
function and I get an error [
Vue warn]: Error in render: "TypeError: member.dateAdded is undefined"
And I can't see why the error is happening since I'm using converting date on other part of my Vue component and I'm not getting this error.
Here is the component I'm getting the error. As you can see, I'm using the toDate
before the table without problem but the one inside the table is giving me the error. When I don't use the function I get this
Timestamp(seconds=1577548891, nanoseconds=834000000)
<template>
<div>
<v-snackbar v-model="snackbar">
<span>Player Added!</span>
<v-btn color="blue" text @click="snackbar = false">Close</v-btn>
</v-snackbar>
<h3 class="font-weight-medium text-center pa-3 ma-3 display-1">Member List</h3>
<template v-if="isMember || isAdmin">
<p
v-for="log in logs"
:key="log.id"
class="body-2 text-right"
>Last Point given @ {{log.time.toDate() | formatDate}}</p>
<p>
<v-simple-table fixed-header height="70vh">
<template v-slot:default>
<thead>
<tr>
<th class="text-left title">Name</th>
<th class="text-left title">Added</th>
</tr>
</thead>
<tbody>
<tr v-for="(member, index) in members" :key="index">
<td>{{member.name}}</td>
<td>{{member.dateAdded.toDate() | formatDate}}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</p>
</template>
</div>
</template>
<script>
import { db, fv, tstp } from "../data/firebaseInit";
import firebase from "firebase/app";
import Popup from "../components/Popup";
import moment from "moment";
export default {
components: { Popup },
data() {
return {
isAdmin: false,
isMember: false,
snackbar: false,
members: [],
logs: [],
user: null
};
},
filters: {
formatDate: function(value) {
if (value) {
return moment(value).format("DD/MMM/YYYY HH:mm");
}
}
},
created() {
this.fetchDb();
},
methods: {
fetchDb() {
db.collection("members")
.orderBy("name")
.onSnapshot(snap => {
const members = [];
snap.forEach(doc => {
let newPlayer = doc.data();
newPlayer.id = doc.id;
members.push(newPlayer);
});
this.members = members;
this.user = firebase.auth().currentUser.displayName;
});
db.collection("pointLog")
.orderBy("time", "desc")
.limit(1)
.onSnapshot(snap => {
const logs = [];
snap.forEach(doc => {
let newLog = doc.data();
newLog.id = doc.id;
logs.push(newLog);
});
this.logs = logs;
});
}
}
}
};
</script>
And here is the component that is adding the timestamp to the firestore
<template>
<v-dialog max-width="600px" v-model="dialog" v-if="isAdmin">
<template v-slot:activator="{ on }">
<v-icon color="green" x-large bottom right v-on="on">mdi-plus-circle</v-icon>
</template>
<v-card>
<v-toolbar flat>
<v-toolbar-title>Add Player</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field required label="Player Name" v-model="name"></v-text-field>
<v-btn text class="success" @click="onSubmit()">Add Player</v-btn>
</v-form>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import { db, tstp } from "../data/firebaseInit";
import firebase from "firebase/app";
export default {
data() {
return {
name: null,
};
},
submited: {
name: "",
dialog: "",
},
methods: {
onSubmit() {
db.collection("members")
.add({
name: this.name,
dateAdded: tstp.fromDate(new Date()),
})
.then(() => {
this.dialog = false;
this.$emit("playerAdded");
})
.catch(err => console.log(err));
}
}
};
</script>
<style>
</style>
Could anyone shed my some light on this?
Upvotes: 0
Views: 520
Reputation: 83163
This is most probably because, for some elements of the members
array, there is no dateAdded
value.
Without seeing your data it is difficult to know what is the exact reason, but one of the most likely possible causes is documents in your members
collection without a dateAdded
field;
One possible way to deal with this problem is to do as follows:
<td v-if="member.dateAdded">{{member.dateAdded.toDate() | formatDate}}</td>
<td v-else>-</td>
In addition, note that it would be better to use the get()
method instead of the onSnapshot()
one, since you only want to query once the Firestore collections.
You could chain the two calls as follows:
fetchDb() {
db.collection("pointLog")
.orderBy("time", "desc")
.limit(1)
.get()
.then(snap => {
const logs = [];
snap.forEach(doc => {
let newLog = doc.data();
newLog.id = doc.id;
logs.push(newLog);
});
this.logs = logs;
return db
.collection("members")
.orderBy("name")
.get();
})
.then(snap => {
const members = [];
snap.forEach(doc => {
let newPlayer = doc.data();
newPlayer.id = doc.id;
members.push(newPlayer);
});
this.members = members;
this.user = firebase.auth().currentUser.displayName;
});
}
Upvotes: 2