I’m working on a vuejs/(vuex) for state management/firebase project of posts.
So I have a firestore collection of posts (array of objects that have name id owner content and timestamp for creation …)
I’m retrieving that data by using the onSnapshot methode and it’s stored on blogPosts variable… and we show theme all, when a user want to visit a single post it will redirect him to the route of the single post (…./view-post/postid) and i filter that array using the id of the post to have an array of one element (which is the post he visited)
when the filter complete i got all the data and i fill theme on the template like these
<template>
<NavBarView />
<section class="preview" v-if="currentBlog">
<h2>{{ currentBlog[0].blogTitle }}</h2>
<p>Posted on: <span>{{ dateFormat() }}</span> <span v-if="currentBlog[0].editTime">(Last edit:
{{ editFormat() }})</span></p>
<img class="blogCover" :src="currentBlog[0].blogCoverFileURL" :alt="currentBlog[0].blogCoverPhoto">
<div class="html-blog" v-html="currentBlog[0].blogHTML"></div>
<hr />
</section>
</template>
<script>
export default {
data() {
return {
currentBlog: null
}
},
mounted: {
this.currentBlog = this.blogPosts.filter((post) => {
return post.blogID == this.$route.params.id
})
},
computed: {
...mapState(['blogPosts'])
}
//note that i have exported all the requirements such as mapState and firebase functions ... didn't write theme here
}
</script>
now the problem is that the filter is occurring before the data are fetched from firebase and i can’t handle that so it’s always returning can’t read property of null (currentBlog[0])
i found a solution which is sending a getDoc request to firebase but it’s a bad idea, (why i send request and i have all the posts here so i can filter it directly and get the specific post) which didn’t work!!!!!
any solution??
2
Answers
I would suggest that rather than trying to do this operation once on
mounted
that you instead re-run the filter every time thatstate.blogPosts
is updated. You can easily do this through a computed property. See below:Looking at your template, I’m under the impression
currentBlog
should not be an array, as you don’t ever have more than 1 element in that array (you’re filtering byblogID
, which I’m guessing is a unique identifier). You need to.find()
the blog entry, not.filter()
it:Note: if
state.blogPosts
does not start as an empty array (as it should), you might want to use:And now replace all
currentBlog[0]
s withcurrentBlog
:Important: make sure in every single method/computed/watch in the script part of the component, if using
currentBlog
, you’re first checking if it’s not falsy. Generic example: