Turn off light
← Back

Listing category name for sorting

May 13, 2021

code

placeholder

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

index.vue
async asyncData({ $content }) {
const categories = await $content('products')
    .only([ 'category' ])
    .fetch()
return { categories }

2. Create array of those category names

index.vue
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.

index.vue
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

index.vue
<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

index.vue
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.

index.vue
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.

index.vue
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/

The Blog of Rizal Renaldi

2021 © rizalrenaldi.com — Made with 🖖

rizalrenaldi.com

Tweet