Adding Getters to a Vuex Store
Tags: webdev, programming, javascript, vue
Published: 2021-01-26 01:16:40

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

With Vuex, we can store our Vue app’s state in a central location.

In this article, we’ll look at how to add getters to a Vuex store to add states derived from other store states.

Adding Getters to Our Store
===========================

We can add a getter to our Vuex store by adding a `getters` property as follows:

`index.js` :

```
const store = new Vuex.Store({  
  state: {  
    todos: [  
      { id: 1, text: "todo1", done: true },  
      { id: 2, text: "todo2", done: false }  
    ]  
  },  
  getters: {  
    doneTodos: state => {  
      return state.todos.filter(todo => todo.done);  
    }  
  }  
});

new Vue({  
  el: "#app",  
  store,  
  computed: {  
    doneTodos() {  
      return this.$store.getters.doneTodos;  
    },  
    ...Vuex.mapState({  
      todos: "todos"  
    })  
  }  
});
```

`index.html` :

```
<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vuex"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <p>Todos:</p>  
        <div v-for="todo of todos">{{todo.text}}</div>  
        <p>Done Todos:</p>  
        <div v-for="todo of doneTodos">{{todo.text}}</div>  
      </div>  
    </div>  
    <script src="index.js"></script>  
  </body>  
</html>
```

In the code, we have a `getters` object:

```
getters: {  
  doneTodos: state => {  
    return state.todos.filter(todo => todo.done);  
  }  
}
```

that derives the state from the `todos` state.

Then we accessed `doneTodos` getter by writing:

```
computed: {  
  doneTodos() {  
    return this.$store.getters.doneTodos;  
  },  
  ...Vuex.mapState({  
    todos: "todos"  
  })  
}
```

in the Vue instance.

Then the items are rendered in our template and we get:

```
Todos:todo1  
todo2  
Done Todos:todo1
```

displayed.

Method-Style Access
===================

We can return a function in a getter function so that we can call the getters from a component with one or more arguments.

For instance, if we want to make a getter that gets a todo by ID, we can write the following:

`index.js` :

```
const store = new Vuex.Store({  
  state: {  
    todos: [  
      { id: 1, text: "todo1", done: true },  
      { id: 2, text: "todo2", done: false }  
    ]  
  },  
  getters: {  
    getTodoById: state => id => {  
      return state.todos.find(todo => todo.id === id);  
    }  
  }  
});

new Vue({  
  el: "#app",  
  store,  
  computed: Vuex.mapState({  
    todos: "todos"  
  }),  
  methods: {  
    getTodoById(id) {  
      return this.$store.getters.getTodoById(id);  
    }  
  }  
});
```

`index.html` :

```
<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vuex"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{getTodoById(1).text}}  
    </div>  
    <script src="index.js"></script>  
  </body>  
</html>
```

Then we see `todo1` displayed on the screen.

We have the following code to define our getter:

```
getters: {  
  getTodoById: state => id => {  
    return state.todos.find(todo => todo.id === id);  
  }  
}
```

The code above returns a function and then returns a todo with the given ID.

Then we access it in our Vue instance by defining the `getTodoById` method as follows:

```
getTodoById(id) {  
  return this.$store.getters.getTodoById(id);  
}
```

Finally, we render it in our template by writing:

```
{{getTodoById(1).text}}
```

The mapGetters Helper
=====================

We can use the `mapGetters` helper to map our getters to computed properties as follows:

`index.js` :

```
const store = new Vuex.Store({  
  state: {  
    todos: [  
      { id: 1, text: "todo1", done: true },  
      { id: 2, text: "todo2", done: false }  
    ]  
  },  
  getters: {  
    doneTodosCount: state => {  
      return state.todos.filter(todo => todo.done).length;  
    }  
  }  
});

new Vue({  
  el: "#app",  
  store,  
  computed: Vuex.mapGetters(["doneTodosCount"])  
});
```

`index.html` :

```
<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.j"></script>  
    <script src="https://unpkg.com/vuex"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{doneTodosCount}}  
    </div>  
    <script src="index.js"></script>  
  </body>  
</html>
```

Then we get 1 displayed since we mapped `doneTodosCount` getter to a computed property with the same name with:

```
computed: Vuex.mapGetters(["doneTodosCount"])
```

Conclusion
==========

We can use getters to add states that are derived from another state.

To define a getter, we add a method to the `getters` property that returns something derived from the state or a function that derives something from a state.

To include it in our components, we can use the `this.$store.getters` method or use the `mapGetters` method.