Search code examples
javascriptvue.jsaxiosvuex

vuex and axios debugging


I'm going crazy, I have a working api that sends data, I connected it to a VueJS app and it was working fine. I'm trying to implement Vuex and I'm stuck. Here's my store.js file

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios'
Vue.use(Vuex);

const state = {
        message: "I am groot",
        articles: []
    }
const getters = {
        getArticles: (state) => {
            return state.articles;
        }
    }
const actions = {
          getArticles: ({ commit }, data) => {
            axios.get('/articles').then( (articles) => {
                commit('GET_ARTICLES', articles);
                console.log(articles); // Trying to debug
            }, (err) => {
                console.log(err);
            })
          }
    }
const mutations =  {
        GET_ARTICLES: (state, {list}) => {
            state.articles = list;
        }   
    }
const store = new Vuex.Store({
    state,
    getters,
    mutations,
    actions,
    mutations
});
console.log(store.state.articles); // this lines works but data is empty
export default store

The console.log within axios call doesn't run and store.state.articles is empty. I must be missing something. I'm just trying to console the articles data on page load...

Please help, I'm near insanity :)

Component :

<template>
  <div class="container">
    <h1>Test component yo !</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
    export default {
        name: 'Test',
        computed: {
            message() {
                return this.$store.state.message
            }
        },
        mounted: () => {
            this.$store.dispatch('getArticles')
        }

    }
</script>

App.js :

import Vue from 'vue';
import ArticlesViewer from './articles_viewer.vue';
import UserArticles from './user_articles.vue';
import App from './app.vue'
import store from './store'

new Vue({
  el: '#app-container',
  store,
  render: h => h(App)
})

Solution

  • You define the mounted lifecycle hook of your component using an arrow function.

    As per the documentation:

    Don’t use arrow functions on an instance property or callback (e.g. vm.$watch('a', newVal => this.myMethod())). As arrow functions are bound to the parent context, this will not be the Vue instance as you’d expect and this.myMethod will be undefined.

    You should define it like so:

    mounted: function () {
      this.$store.dispatch('getArticles');
    }
    

    Or, use the ECMAScript 5 shorthand:

    mounted() {
      this.$store.dispatch('getArticles');
    }
    

    Now, your dispatch method will be called correctly, populating your articles array.