Search code examples
vue.jsvuejs2vuexvue-resource

Using Vue-Resource in Vuex store; getting maximum call stack size error


I'm trying to pull an array from my api to a component using vuex but I'm at a loss and probably in over my head in attempting this. With the api being accessed directly from a component I had it set up like this and it was fine:

data () {
 return {
  catalog:[],
 }
},
created() {
 this.$http.get('https://example.net/api.json').then(data => {
  this.catalog = data.body[0].threads;
 })
}

For reference the json looks similar to this:

[{
"threads": [{
 "no: 12345,
 "comment": "comment here",
 "name": "user"
}, {
 "no: 67890,
 "comment": "another comment here",
 "name": "user2"
}],

//this goes on for about 15 objects more in the array

 "page": 0
}]

When I move this all to store I'm losing grasp on how to actually make this work. I've used vuex before just never with vue-resource.

//store.js

state: {
    catalog: []
},
actions: {
    getCatalog({commit}){
        Vue.http.get('https://example.net/api.json').then(response => {
            commit('LOAD_CATALOG', response.data.data)
        });
    }
},
mutations: {
    LOAD_CATALOG (state) {
        state.catalog.push(state.catalog)
    }
},
getters: {
    catalog: state => state.catalog,
}

//component.vue

created () {
    this.$store.dispatch('getCatalog')
},
computed: {
    catalog () {
        return this.$store.getters.catalog
    }
}

I'm aware this is wrong and I'm getting max call stack size errors. How can I get the same results as posted in the example above (this.catalog = data.body[0].threads;) when I put everything in store?

Let me know if anything needs clarification! I'm still pretty new at using Vue 2.0.


Solution

  • Your main issue is with your mutation.

    Mutations are synchronous updates to the state, therefore you are correctly calling it from the action (where you process your async request) but you aren't passing the mutation anything to place in the state. Mutations accept arguments, so your LOAD_CATALOG mutation would accept the catalogData, i.e.

    mutations: {
        LOAD_CATALOG (state, catalogData) {
            state.catalog = catalogData
        }
    },
    

    Also if you are using vue resource for Vue 2 then you should be passing the body of the response to the mutation, i.e.

    getCatalog({commit}){
        Vue.http.get('https://example.net/api.json').then(response => {
            commit('LOAD_CATALOG', response.body[0].threads)
        });
    }
    

    The next issue is you don't need the getter, getters allow us to compute a derived state, you don't need them just to return an existing state (in your case catalog). A basic example of where you may use a getter would be to add 1 to a counter stored in state, i.e.

    getters: {
        counterAdded: state => state.counter + 1,
    }
    

    Once you've made these changes things will look a bit more like below:

    //store.js
    
    state: {
        catalog: []
    },
    
    actions: {
        getCatalog({commit}){
            Vue.http.get('https://example.net/api.json').then(response => {
                commit('LOAD_CATALOG', response.body[0].threads)
            });
        }
    },
    
    mutations: {
        LOAD_CATALOG (state, catalogData) {
            state.catalog = catalogData
        }
    },
    
    //component.vue
    
    created () {
        this.$store.dispatch('getCatalog')
    },
    
    computed: {
        catalog () {
            return this.$store.state.catalog
        }
    }