Search code examples
vue.jscomputed-properties

Vuejs2 - List rendering filtered with computed properties


I've some problems with list rendering and filtering the data with computed properties

Instead of hardcoded row.age value, I'd like to use filterKey to filter row.age.

How to archieve this? I just don't get it.

Here's my example:

template:

<button type="button" class="btn btn-t1-secondary" v-on: click="filterKey = '15'">11</button>
<button type="button" class="btn btn-t1-secondary" v-on: click="filterKey = '30'">8</button>

<table>
    <thead>
        <tr>
            <th>Category</th>
            <th>Age</th>
            <th>Food</th>
        </tr>
    </thead>
    <tbody>
        <tr v-for="row in filteredCategory">
            <td>{{ row.category }}</td>
            <td>{{ row.age }}</td>
            <td>{{ row.food }}</td>
        </tr>
    </tbody>
</table>

JavaScript:

<script>
var app = new Vue({
  el: '#app',
  data: {
    filterKey: '',
    filterCategory: '',
    dataToFilter: [
      {
        category: 'dog',
        age: '11',
        food: 'bone'
      },
      {
        category: 'cat',
        age: '8',
        food: 'fish'
      }
      //etc.
    ]
  },
  computed: {
    filteredCategory() {
      return this.dataToFilter.filter(function (row) {
        return row.category === 'dog'
      })
        .filter(function (row) {
          console.log(this.filterKey)
          return row.age === '15'
        })
    },
  }
})
</script>

Solution

As @Sadraque_Santos suggested, I used arrow functions.

Code

filteredCategory() {
return this.dataToFilter.filter( r => r.category === 'dog' && r.age === this.filterKey);
}

Also, I have to support IE11 so I just use Babel to compile the code for me.


Solution

  • To have access to this inside a filter, map or another useful method you must learn about arrow functions, they allow you to create a function without the this bound to that object, so instead of using:

    filteredCategory () {
      return this.dataToFilter.filter(function (row) {
        return row.category === 'dog'
      })
        .filter(function (row) {
          console.log(this.filterKey)
          return row.age === '15'
        })
    }
    

    Your code should be like this:

        filteredCategory () {
          return this.dataToFilter
            .filter((row) => row.category === this.filterCategory)
            .filter((row) => row.age === this.filterKey)
        }