Erik
Erik

Reputation: 101

vuex - unknown action type (can't dispatch my action)

I was trying moving my store into separate modules and couldn't figure out how to dispatch my actions. I can access the state values, but not the action.

Bear in mind this project I'm doing exclusively to learn vue, so I'm definitely a beginner here.

src/store/store.js (acts as my index inside the store folder)

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

import posts from './modules/posts'
import comments from './modules/comments'

Vue.use(Vuex)
axios.defaults.baseURL = 'https://someapi.com/'

export default new Vuex.Store({
    name: 'store',
    namespaced: true,
    modules: {
      posts,
      comments
    },
})

src/store/modules/posts.js

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)
axios.defaults.baseURL = 'https://someapi.com/'

export default new Vuex.Store({
    name: 'posts',
    state: {
        posts: [],
        post: {}
    },
    mutations: {
        retrievePosts(state, posts){
            state.posts = posts
        },
        retrievePost(state, post){
            state.post = post
        },
    },
    actions: {
        retrievePosts (context) {
            axios.get('/blog/post/all')
                .then(response => {
                    var posts = response.data.data
                    context.commit('retrievePosts', posts)
                })
                .catch(error => {
                    console.log(error)
                })
            },
            retrievePost (context, slug) {
                axios.get('/blog/post/all')
                    .then(response => {
                        var post = response.data.data[1]
                        context.commit('retrievePost', post)
                    })
                    .catch(error => {
                        console.log(error)
                    })
            },
    }

})

src/components/BlogPostList.vue

<template>
    <div class="postList">
        <b-container v-for="post in this.$store.state.posts.posts" :key="post.id" class="post">
            <b-row>
                <b-col>
                    <h1><a :href="'post/' + post.slug">{{ post.title }}</a></h1>
                </b-col>
            </b-row>
            <b-row>
                <b-col cols="10">
                    <h4>{{ post.subtitle }}</h4>
                </b-col>
                <b-col>
                    <small>by {{ post.author_id }} </small>
                </b-col>
            </b-row>
            <b-row>
                <b-col>
                    <!-- <p v-html="post.body.substring(0, 1000) + '...'"></p> -->
                    <span class="post-text" v-html="post.body"/>
                </b-col>
            </b-row>
            <br />
            <b-row>
                <b-col>
                    <dx-button style="float:right"
                        text="read more"
                        @click="buttonClicked" 
                    />
                </b-col>
            </b-row>
            <hr>
        </b-container>
    </div>
</template>

<script>
import DxButton from "devextreme-vue/button";

export default  {
    components: {
        DxButton
    },
    name: 'BlogPostList',
    created () {
        this.$store.dispatch('retrievePosts')
    },
    methods: {
        buttonClicked: function() {
            alert("The Button was clicked");
        }
    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.postList {
    h1 {
        font-size: 50px;
    }
    .post-text {
        text-align: justify;
    }
}
</style>

I've tried the most "recommended" fix I found, which is changing

this.$store.dispatch('retrievePosts')

to

this.$store.dispatch('posts/retrievePosts')

but I get the same error on console...

Thanks in advance!

Upvotes: 0

Views: 2867

Answers (1)

Ana Liza Pandac
Ana Liza Pandac

Reputation: 4861

This might be because you created another Vuex store inside your posts module which you've added as module in your main store.js.

Try modifying your posts module to the following.

import axios from 'axios';

axios.defaults.baseURL = 'https://someapi.com/';

export default {
  name: 'posts',
  state: {
    posts: [],
    post: {}
  },
  mutations: {
    retrievePosts(state, posts) {
      state.posts = posts;
    },
    retrievePost(state, post) {
      state.post = post;
    }
  },
  actions: {
    retrievePosts(context) {
      axios
        .get('/blog/post/all')
        .then((response) => {
          var posts = response.data.data;
          context.commit('retrievePosts', posts);
        })
        .catch((error) => {
          console.log(error);
        });
    },
    retrievePost(context, slug) {
      axios
        .get('/blog/post/all')
        .then((response) => {
          var post = response.data.data[1];
          context.commit('retrievePost', post);
        })
        .catch((error) => {
          console.log(error);
        });
    }
  }
};

Upvotes: 2

Related Questions