Search code examples
vue.jsnuxt.jsvuexstoregetter

Nuxt store getter not working, ID given to payload is not an Integer + Error: [vuex] do not mutate vuex store state outside mutation handlers


I am trying to make a product detail page. The detail page is named _id. When opened the id is replaced with the product id. On opening the page the state is set with data fetched from an api.

After that i am trying to use a computed property that refers to a getter named getProduct() with an id (this.$route.params.id) in the payload.

This is how my _id.vue looks like:

methods: {
  ...mapActions("products", ["fetchProducts",]),
  ...mapGetters("products", ["getProduct",]),
},
async mounted() {
  this.fetchProducts()
},
computed: {
  product() {
    return this.getProduct(this.$route.params.id)
  }
}

This is how my store file named products.js looks like:

import axios from "axios"

export const state = () => ({
  producten: []
})

export const mutations = {
  setProducts(state, data) {
    state.producten = data
  }
}

export const getters = {
  getProduct(state, id) {
    console.log(id)
    return state.producten.filter(product => product.id = id)
  }
}

export const actions = {
  async fetchProducts({ commit }) {
    await axios.get('/api/products')
      .then(res => {
        var data = res.data
        commit('setProducts', data)
      })
      .catch(err => console.log(err));
  }
}

What works is creating the state, but when i try to use the getter something goes wrong. As you can see i console.log() the id given to it. Which logs the following:

I also get the error: client.js?06a0:103 Error: [vuex] do not mutate vuex store state outside mutation handlers.

Which I'm not doing as far as I know?

**Note: **these errors get logged as much as the length of my state array is.


Solution

  • From the Vuex documentation:

    Vuex allows us to define "getters" in the store. You can think of them as computed properties for stores. Like computed properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.

    Like computed, getters does not support having arguments.

    But there is a way to have "method-style access" to a getter: https://vuex.vuejs.org/guide/getters.html#property-style-access

    You can also pass arguments to getters by returning a function. This is particularly useful when you want to query an array in the store:

    getters: {
      // ...
      getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
      }
    }
    
    store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
    

    Note that getters accessed via methods will run each time you call them, and the result is not cached.