In a Cloud Firestore document, in a collection titled reviews, I have a field titled createdAt of timestamp type.
I'm trying to display that createdAt field in the DOM using the date-fns date utility library's formatDistanceToNow, which returns the distance between the given date and now in words, such as "less than a minute" ago.
For example, in a given Firestore document, createdAt is of timestamp type with the value 11/14/2021 10:49:09 AM
I am able to access and display the createdAt field, as follows:
<p>{{ review.createdAt }}</p> results in this in the the DOM: Timestamp(seconds=1636904949, nanoseconds=271000000)
<p>{{ review.createdAt.toDate() }}</p> results in this in the the DOM: Sun Nov 14 2021 10:49:09 GMT-0500 (Eastern Standard Time)
I am trying to display the date-fns formatted date as follows:
In the <template> section: <p>{{ computedDateToNow }}</p>
And in the <script> section:
const computedDateToNow = computed(() => {
return formatDistanceToNow(review.createdAt.toDate())
})
console.log(computedDateToNow)
And the error I'm getting in the console is
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'toDate')
at ReactiveEffect.eval [as fn] (ReviewDetails.vue?5986:590)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
at ComputedRefImpl.get value [as value] (reactivity.esm-bundler.js?a1e9:1087)
at unref (reactivity.esm-bundler.js?a1e9:1001)
at Object.get (reactivity.esm-bundler.js?a1e9:1004)
at Proxy.render (ReviewDetails.vue?5986:34)
at renderComponentRoot (runtime-core.esm-bundler.js?5c40:756)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?5c40:4594)
at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6987)
review.createdAt and review.createdAt.toDate() are displaying just fine in the DOM, between the <p> tags.
Why is the toDate() method (link to that in Firebase docs) causing a problem in computedDateToNow?
UPDATE Based on this comment that "It is very likely that this javascript function was placed before the actual html was loaded" I added an if (review.createdAt) statement and the error goes away, BUT review.createdAt is still undefined in console.log(computedDateToNow)
Here's the code block, with the if statement:
const computedDateToNow = computed(() => {
if (review.createdAt) {
console.log('begin new console dot log',review.createdAt,'end new console dot log')
return formatDistanceToNow(review.createdAt.toDate())
}
})
ADDED (in response to @Raffobaffo's request):
<script>
import useDocument from '@/composables/useDocument'
import getDocument from '@/composables/getDocument'
import { computed } from 'vue'
import { formatDistanceToNow } from 'date-fns'
export default {
props: ['id'],
components: { },
setup(props) {
const { error, document: review } = getDocument('reviews', props.id)
const { deleteDoc, updateDoc } = useDocument('reviews', props.id)
// BEGIN formatting timestamp
console.log('begin new console dot log',review.createdAt,'end new console dot log')
const computedDateToNow = computed(() => {
if (review.createdAt) {
console.log('begin new console dot log',review.createdAt,'end new console dot log')
return formatDistanceToNow(review.createdAt.toDate())
}
})
console.log(computedDateToNow)
// END formatting timestamp
return { error, review, formatDistanceToNow, computedDateToNow }
}
}
</script>
Thanks for any help!