Search code examples
javascriptvue.jsvuexvuex-modules

Vuex Getter Undefined


I am new to Vue.js and experiencing an issue with Vuex modules and Axios. I have a "post" component that retrieves a slug from the router and fetches data with Axios which is then retrieved with Vuex Getters.

I am able to retrieve data successfully but then I still see this error on my DevTools, "TypeError: Cannot read property 'name' of undefined"

Due to this error I am not able to pass this.post.name to Vue-Meta.

Codes

Post.vue

  computed: {
    ...mapGetters(["post"]),
  },

  mounted() {
    const slug = this.$route.params.slug;
    this.fetchPost({ slug: slug });
  },

  methods: {
    ...mapActions(["fetchPost"]),

/store/modules/post.js

const state = {
  post: [],
};

const getters = {
  post: (state) => {
    return post;
  }
};

const actions = {
  async fetchPost({ commit }, arg) {
    try {
      await axios.get("/post/" + arg.slug).then((response) => {
        commit("setPost", response.data);
      });
    } catch (error) {
      console.log(error);
    }
  },
};

const mutations = {
  setPost: (state, post) => (state.post = post),
};

export default {
  state,
  getters,
  actions,
  mutations,
};


Solution

  • Your getter is utterly wrong: a state getter is supposed to be a function that takes in the entire state as a param and retrieves whatever you're interested in from it. Your version...

    const getters = {
      post: (state) => {
       return post;
      }
    };
    

    ...takes in the state as a param but doesn't use it. Instead, it returns a variable (post) which has not been defined in that context.
    Which will always return undefined, regardless of current value of state.post.
    And, as you already know, JavaScript can't access property 'name' of undefined.

    To get the current value of state.post, use:

    const getters = {
      post: state => state.post
    }
    

    Or

    const getters = {
      post: (state) => { return state.post; }
    }
    

    ... if you fancy brackets.

    Also, out of principle, I suggest initializing your post with an empty object {} instead of an empty array []. Changing variable types as few times as possible is a very good coding habit, providing huge benefits in the long run.


    Edit (after [mcve])

    You have a bigger problem: the import from your axios plugin returns undefined. So you can't call get on it. Because you wrapped that call into a try/catch block, you don't get to see the error but the endpoint is never called.
    I don't know where you picked that plugin syntax from but it's clearly not exporting axios. Replacing the import with import axios from 'axios' works as expected.

    Another advice would be to namespace your store module. That's going to become useful when you'll have more than one module and you'll want to specifically reference a particular mutation/action on a specific module. You'll need to slightly change mapActions and mapGetters at that point.

    See it working here.