How do I use vuex module actions of axios ?
-
Hello,
I am quite new to quasar and I try to convert my Vue app to quasar but now I am having problem to fetch data using my vuex namespaced modules.const getDefaultState = () => { return { indexArticles: [], } } const state = getDefaultState() const getters = { indexArticles (state) { return state.indexArticles }, } const mutations = { fetchStart (state) { state.loading = true }, fetchEnd (state) { state.loading = false }, setIndexArticles (state, pArticles) { state.indexArticles = pArticles state.errors = {} } } const actions = { fetchIndexArticles (context) { context.commit('fetchStart') return this.$axios.get('articleslist/index/') .then((data) => { console.log(data) context.commit('setIndexArticles', data.data) context.commit('fetchEnd') }) .catch((response) => { context.commit('setError', response.data.errors) }) }, } export default { namespaced: true, state, getters, actions, mutations }
now I try to reach my files in my Index.vue
<script> import { mapGetters } from 'vuex' export default { name: 'PageIndex', computed: { ...mapGetters('articles', ['indexArticles']), articles () { return this.$store.dispatch('articles/fetchIndexArticles') } }, created () { this.$store.dispatch('articles/fetchIndexArticles') .then(() => { this.isLoading = false }) } } </script>
In the console error is:
vue.runtime.esm.js?5593:1888 TypeError: Cannot read property 'get' of undefined at Store.fetchIndexArticles (articles.js?5e84:163) at Array.wrappedActionHandler (vuex.esm.js?94e4:847) at Store.dispatch (vuex.esm.js?94e4:512) at Store.boundDispatch [as dispatch] (vuex.esm.js?94e4:402) at VueComponent.created (Index.vue?b484:299) at invokeWithErrorHandling (vue.runtime.esm.js?5593:1854) at callHook (vue.runtime.esm.js?5593:4219) at VueComponent.Vue._init (vue.runtime.esm.js?5593:5008) at new VueComponent (vue.runtime.esm.js?5593:5154) at createComponentInstanceForVnode (vue.runtime.esm.js?5593:3283)
my quasar info
Operating System - Linux(5.9.6-arch1-1) - linux/x64 NodeJs - 12.19.0 Global packages NPM - 6.14.8 yarn - 1.22.5 @quasar/cli - 1.1.2 @quasar/icongenie - Not installed cordova - Not installed Important local packages quasar - 1.14.3 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time @quasar/app - 2.1.6 -- Quasar Framework local CLI @quasar/extras - 1.9.10 -- Quasar Framework fonts, icons and animations eslint-plugin-quasar - Not installed vue - 2.6.12 -- Reactive, component-oriented view layer for modern web interfaces. vue-router - 3.2.0 -- Official router for Vue.js 2 vuex - 3.5.1 -- state management for Vue.js electron - Not installed electron-packager - Not installed electron-builder - Not installed @babel/core - 7.12.3 -- Babel compiler core. webpack - 4.44.2 -- Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff. webpack-dev-server - 3.11.0 -- Serves a webpack app. Updates the browser on changes. workbox-webpack-plugin - Not installed register-service-worker - 1.7.1 -- Script for registering service worker, with hooks typescript - 3.9.5 -- TypeScript is a language for application scale JavaScript development @capacitor/core - Not installed @capacitor/cli - Not installed @capacitor/android - Not installed @capacitor/ios - Not installed Quasar App Extensions *None installed* Networking Host - ytsejam wlp3s0 - 192.168.0.2
how can I fix and fetch the articles?
-
what is the code listing of your
/src/boot/index.js
file? -
Here’s a repo of a Quasar project with vuex modules( and a lot of other advanced features):
https://github.com/vycoder/qodo -
import axios from 'axios' axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN' axios.defaults.xsrfCookieName = 'csrftoken' axios.defaults.withCredentials = true const axiosInstance = axios.create({ baseURL: 'http://localhost:8000/api/' }) export default async ({ Vue }) => { axiosInstance.interceptors.response.use(null, error => { if (error.response.data) { Object.keys(error.response.data).forEach(key => { const data = error.response.data if (Array.isArray(data[key])) { data[key] = data[key].join(' ') } }) return Promise.reject(error) } }) Vue.prototype.$axios = axiosInstance } export { axiosInstance }
this my /src/boot/axios.js file and I use it in boot in quasar.conf.js . I can see the data if I use this.$axios(‘api_address’) and console.log it. but could not reach from computed.
-
Sorry what i meant was
/src/store/index.js
. But please check the repo in my previous post. Working code will explain it better than I can. -
export default function (/* { ssrContext } */) { const Store = new Vuex.Store({ modules: { articles, books, members, pages, status, user, videolessons }, // enable strict mode (adds overhead!) // for dev mode only strict: process.env.DEBUGGING, plugins: [createPersistedState({})] }) return Store } ``` I am trying to find an vuex dispatch in it.
-
computed: { ...mapGetters('articles', ['indexArticles']), articles () { return this.$store.dispatch('articles/fetchIndexArticles') }
this code looks weird. You define
acticles
twice in this component. Once by using mapgetters and twice by mappingarticles()
to a store action on the next line. -
I tried both ways, If anything solves, but none of them worked that is why there is two different methods.
-
Ah I see, do please take a look at :
https://github.com/vycoder/qodoI am sure it will help a lot.
-
@ytsejam try not only importing …mapGetters also …mapActions. In your methods try this:
methods: {
…mapActions(‘store_name’, [‘actions’,[‘anotherAction’]])
}use that action to fill your state with data and the getters just to obtain the value from your state
-
This is not in documents but when booting axios
import axios from 'axios' export default ({ store, Vue }) => { Vue.prototype.$axios = axios store.$axios = axios }
-
Perhaps the original issue was that his store was not namespaced, but was using it in that manner.
-
My solutlion as late March 2021:
import Vue from 'vue' import Axios from 'axios' const BASE_URL = process.env.API || 'http://localhost:3000/' const axios = Axios.create({ baseURL: BASE_URL, timeout: 1000, headers: { 'Content-Type': 'application/json' } }) Vue.prototype.$axios = axios export { axios }