Mapped Vuex function "is not a function", but still loads - vue.js

When I call a mapped Vuex action in my mounted hook, the action works, but I get "TypeError: xxx is not a function" error in the console.
Here's my whole script section for this component:
<script>
import SideNav from '#/components/SideNav.vue'
import ActionBar from '#/components/ActionBar.vue'
import Summaries from '#/components/Summaries.vue'
import { mapState, mapActions } from 'vuex'
export default {
components: { SideNav, ActionBar, Summaries },
computed: {
...mapState(['dataLoading']),
...mapActions(['init'])
},
mounted() {
this.init();
}
}
</script>

You should map Actions as methods instead of computed, see dispatch actions in components:
computed: {
...mapState(['dataLoading'])
},
methods: {
...mapActions(['init'])
},
mounted() {
this.init();
}

Related

how to use v model if using vuex

how to use v-model on vuex,
in this case only to show modal box when button is clicked
in this vuex also have separate to module
this is index module
import createPersistedState from 'vuex-persistedstate'
import Vue from 'vue'
import Vuex from 'vuex'
import authentication from './authentication'
import products from './products'
import projects from './projects'
Vue.use(Vuex)
export default new Vuex.Store({
strict: true,
state: {
baseUrl: '/api',
// baseUrl: 'http://localhost:3333/api',
},
mutations: {
},
actions: {
},
modules: {
authentication,
products,
projects,
},
plugins: [
createPersistedState(),
],
})
and this is my module
import HTTP from '../http';
export default {
namespaced: true,
state:{
dialog: false,
},
getters: {
dialog(state){
console.log(state.dialog)
return state.dialog
}
},
mutations: {
closeCard(state){
state.dialog=false;
console.log(state.dialog);
}
}
}
i have try map state and map getter both not function
and this is my vue code
v-model="dialog"
width="500"
i have try use map state or map getter but both not working
import Test from '/components/Test'
export default {
components:{
Test
},
computed: {
dialog:{
get() {
return this.$store.state.dialog.products
},
},
map State('products',[
'dialog'
]),
},
methods:{
map Actions('products',[
'close Card',
])
}
}
and this is my error
Computed property "dialog" was assigned to but it has no setter.
found in
Directly binding a computed property to a v-model is a bad practice as a computed value doesn't have a default setter.
you will need to implement a setter for your computed value. you can read about it here.
you should implement a state action that changes the value of the dialog property and then call it in your setter (and set it to true or false, depending on the case.
Actually there are typo's in your code while called vuex handlers
import {mapState, mapActions } from 'vuex'; // check this line
import Test from '/components/Test'
export default {
components:{
Test
},
computed: {
dialog:{
return this.dialog;
},
...mapState('products',[ // check this line
'dialog'
]),
},
methods:{
...mapActions('products',[ // check this line
'closeCard', // check this line
])
}
}
Also note that you shouldn't directly bind a computed property to a v-model

Vuex: 'this' is undefined in mapState

I'm trying to map state of dynamic module, but it seems that I don't have access to this inside mapState or mapActions
<script>
import { mapState, mapActions } from 'vuex';
import MachineModule from '../store/modules/machine';
export default {
props: {
machineName: String,
},
created() {
this.$store.registerModule(this.machineName, MachineModule);
},
computed: {
...mapState(this.machineName, ['timesServiced']),
},
methods: {
...mapActions(this.machineName, ['serviceMachine']),
},
};
</script>
I got this error
Uncaught TypeError: Cannot read property 'machineName' of undefined.

unable to retrieve mutated data from getter

I'm trying to render a d3 graph using stored data in vuex. but I'm not getting data in renderGraph() function.
how to get data in renderGraph()?
Following is store methods.
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import * as d3 from "d3";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
subscribers: []
},
getters: {
getterSubscribers: state => {
return state.subscribers;
}
},
mutations: {
mutationSubscribersData: (state, payload) => {
state.subscribers = payload;
}
},
actions: {
actionSubscribersData: async ({ commit }) => {
let subsData = await d3.json("./data/subscribers.json"); // some json fetching
commit("mutationSubscribersData", subsData);
}
}
});
Below is parent component
Home.vue
<template>
<div>
<MyGraph /> // child component rendering
</div>
</template>
<script>
import MyGraph from "./MyGraph.vue";
export default {
components: {
MyGraph
},
};
</script>
Below is child component.
MyGraph.vue
<template>
<div>
<svg width="500" height="400" />
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
computed: {
...mapGetters(["getterSubscribers"])
},
methods: {
...mapActions(["actionSubscribersData"]),
renderGraph(data) {
console.log(data); // DATA NOT COMING HERE
// MyGraph TO BE RENDERED WITH THIS DATA
}
},
mounted() {
this.actionSubscribersData();
this.renderGraph(this.getterSubscribers);
}
};
</script>
I have tried mounted, created lifecycle hooks. but did not find data coming.
There is race condition. actionSubscribersData is async and returns a promise. It should be waited for until data becomes available:
async mounted() {
await this.actionSubscribersData();
this.renderGraph(this.getterSubscribers);
}
There must be delay for the actionSubscribersData action to set value to store. Better you make the action async or watch the getter. Watching the getter value can be done as follows
watch:{
getterSubscribers:{ // watch the data to set
deep:true,
handler:function(value){
if(value){ // once the data is set trigger the function
this.renderGraph(value);
}
}
}
}

Can't access store from Vuex [Quasar]

I'm trying Quasar for the first time and trying to use the Vuex with modules but I can't access the $store property nor with ...mapState. I get the following error 'Cannot read property 'logbook' of undefined' even though I can see that the promise logbook exists on Vue Devtools. Print from Devtools
Here is my store\index.js
import Vue from 'vue';
import Vuex from 'vuex';
import logbook from './logbook';
Vue.use(Vuex);
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
logbook,
},
strict: process.env.DEV,
});
return Store;
}
Here is the component
<template>
<div>
<div>
<h3>RFID</h3>
<q-btn #click="logData"
label="Save"
class="q-mt-md"
color="teal"
></q-btn>
<q-table
title="Logbook"
:data="data"
:columns="columns"
row-key="uid"
/>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'RFID',
mounted() {
this.getLogbookData();
},
methods: {
...mapActions('logbook', ['getLogbookData']),
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
},
data() {
return {
};
},
};
</script>
<style scoped>
</style>
Here is the state.js
export default {
logbookData: [],
};
Error that I get on the console
Update: Solved the problem by refactoring the way I declared the function. I changed from:
logData: () => { console.log(this.loadedLogbook); }
to
logData () { console.log(this.loadedLogbook); }
Check the .quasar/app.js file. Is there a line similar to import createStore from 'app/src/store/index', and the store is later exported with the app in that same file?
I think you confused all the mapx functions.
...mapState and ...mapGetters provide computed properties and should be handled like this
export default {
name: 'RFID',
data() {
return {
};
},
mounted() {
this.getLogbookData();
},
computed: {
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
}
methods: {
...mapActions('logbook', ['getLogbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
}
};

Ho do you call Vuex module Action from Vue component action?

Let's say i have Vuex store module storeModuleName, and i want to invoke its action from some component.
Component:
export default {
actions: {
close() {
dispatch('storeModuleName/storeModuleAction');
},
}
...
Error:
dispatch is not defined
You need mapActions, mapActions let you connect with actions inside modules
import { mapActions } from "vuex";
export default {
methods: {
...mapActions({
storeModuleActionName: "storeModuleName/storeModuleAction"
})
},
mounted(){
this.storeModuleActionName();
}
}
And then you can use storeModuleActionName as a normal method, Check the link about mapActions