What to achieve:
List all category names, for live sorting posts from Nuxt Content
1. Fetch all posts on Nuxt Content and loop through all posts and look for category name on each post
async asyncData({ $content }) {
const categories = await $content('products')
.only([ 'category' ])
.fetch()
return { categories }
2. Create array of those category names
async asyncData({ $content }) {
const categories = await $content('products')
.only([ 'category' ])
.fetch()
const categoriesFilter = products.map((product) => product.category)
return { categories }
3. Remove all duplicates in that categories array and create new array contains each unique category name, and sort it alphabetically.
async asyncData({ $content }) {
const categories = await $content('products')
.only([ 'category' ])
.fetch()
const categoriesFilter = products.map((product) => product.category)
const uniqueItems = new Set(categoriesFilter)
const allCategories = [...uniqueItems].sort()
return { categories, allCategories }
4. View it on page
<button
v-for="(category, index) in filteredProducts"
:key="index"
@click="selectFilter(category)"
>
{{ category }}
</button>
Notice that we loop through filteredProducts, which we'll define later on, and also there's click handler. We want to sort post when any of that category clicked. So we need to create method for this.
5. Create click method for filtered posts
data(){
return{
selected: false
}
},
methods:{
selectFilter(category) {
this.selected === category ? (this.selected = null) : (this.selected = category)
}
},
computed:{
filteredProducts() {
if (!this.selected) return this.products
return this.products.filter((products) => products.category === this.selected)
}
}
First we create data "selected" and set to false, means all posts are now shown.
6. Now we added click handler for any category clicked. Every time a category is clicked, it will be set on selected data.
data(){
return{
selected: false
}
},
methods:{
selectFilter(category) {
this.selected === category ? (this.selected = null) : (this.selected = category)
}
},
7. Last, we filter all posts that have chosen category. We use computed for this.
data(){
return{
selected: false
}
},
methods:{
selectFilter(category) {
this.selected === category ? (this.selected = null) : (this.selected = category)
}
},
computed:{
filteredProducts() {
if (!this.selected) return this.products
return this.products.filter((products) => products.category === this.selected)
}
}
the computed function will check if selected data. If it return false, then show all products. If it return true, then apply that keyword to filter the products and show it in the loop that we defined earlier.
Notes: Thanks to this post on reddit: https://www.reddit.com/r/Nuxt/comments/jawpw2/how_to_get_categories_from_each_products_with/