I have a vuejs ponent and a vuex store.
I would like to send data from vue ponent to vuejs store and then call a function in vuex that's push data to a db.
I get the data from currentUser (that works), but in vuex store I get the error: Cannot read property 'push' of null
.
I run createPost
that works but the data does not pushed to vuex store I think because the error above.
#vuejs ponent
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
import {
SET_NEWPOST,
ADD_TAGS,
SET_USERDATA,
SET_GENERAL
} from "@/store/posts/mutations";
methods: {
...mapMutations("posts", {
updateInformation: SET_NEWPOST,
setUserData: SET_USERDATA,
addGeneral: SET_GENERAL,
addTags: ADD_TAGS
}),
...mapActions("posts", {
create: "triggerAddProductAction"
}),
async createPost() {
this.updateInformation({
content: this.content,
url: this.newOne
});
this.updateUserData();
this.createOne();
}
}
vuex store
...
const state = {
products: []
}
const mutations = {
[addProduct]: (state, product) => state.products.push(product)
},
const actions: {
createUserProduct: async ({ mit, rootState }, product) => {
const userProductDb = new UserProductsDB(
rootState.authentication.user.id
);
const createdProduct = await userProductDb.create(product);
mit("addProduct", createdProduct);
},
triggerAddProductAction: ({ dispatch, state, mit }) => {
const post = state.newPost;
dispatch("createUserProduct", post);
}
}
I have a vuejs ponent and a vuex store.
I would like to send data from vue ponent to vuejs store and then call a function in vuex that's push data to a db.
I get the data from currentUser (that works), but in vuex store I get the error: Cannot read property 'push' of null
.
I run createPost
that works but the data does not pushed to vuex store I think because the error above.
#vuejs ponent
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
import {
SET_NEWPOST,
ADD_TAGS,
SET_USERDATA,
SET_GENERAL
} from "@/store/posts/mutations";
methods: {
...mapMutations("posts", {
updateInformation: SET_NEWPOST,
setUserData: SET_USERDATA,
addGeneral: SET_GENERAL,
addTags: ADD_TAGS
}),
...mapActions("posts", {
create: "triggerAddProductAction"
}),
async createPost() {
this.updateInformation({
content: this.content,
url: this.newOne
});
this.updateUserData();
this.createOne();
}
}
vuex store
...
const state = {
products: []
}
const mutations = {
[addProduct]: (state, product) => state.products.push(product)
},
const actions: {
createUserProduct: async ({ mit, rootState }, product) => {
const userProductDb = new UserProductsDB(
rootState.authentication.user.id
);
const createdProduct = await userProductDb.create(product);
mit("addProduct", createdProduct);
},
triggerAddProductAction: ({ dispatch, state, mit }) => {
const post = state.newPost;
dispatch("createUserProduct", post);
}
}
Share
Improve this question
asked May 1, 2019 at 15:50
lukas34tfdlukas34tfd
1352 gold badges3 silver badges11 bronze badges
5
-
1
You pass the data as the second parameter to
dispatch
, for example to pass a value of1
use:this.$store.dispatch('createUserProduct', 1)
– Get Off My Lawn Commented May 1, 2019 at 15:53 - yeah I understand, but does not helped me – lukas34tfd Commented May 1, 2019 at 15:57
-
const post = ..
is empty and I don't know why – lukas34tfd Commented May 1, 2019 at 15:58 - I think it is because of the way you formatted the object – Get Off My Lawn Commented May 1, 2019 at 15:58
- I tested different ways but each time the same error – lukas34tfd Commented May 1, 2019 at 15:59
2 Answers
Reset to default 3Your format I believe is a little off. Try building the store like this. Remember that using arrow functions vs non-arrow functions can also have a side effect in what is being referenced.
Mostly what can be seen, is that I removed the const
's, and placed it all in the object literal directly. I also remove the Destructuring
of addProduct
as it doesn't seem logical here.
const store = new Vuex.Store({
state: {
products: []
},
mutations: {
addProduct: (state, product) => {
state.products.push(product)
console.log('Added Product:', product)
console.log('products', state.products)
}
},
actions: {
async createUserProduct({ mit }, product) {
mit("addProduct", product);
}
}
});
new Vue({
el: "#app",
store,
mounted() {
this.$store.dispatch('createUserProduct', 1)
}
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/vuex/3.1.0/vuex.min.js"></script>
<div id="app"></div>
I think one of the main problems here is actually that you call mutations directly in your ponent. Mutations should always be called by actions and not directly. This is because mutations are synchronous and actions can be asynchronous. From Vuex docs:
On to Actions Asynchronicity bined with state mutation can make your program very hard to reason about. For example, when you call two methods both with async callbacks that mutate the state, how do you know when they are called and which callback was called first? This is exactly why we want to separate the two concepts. In Vuex, mutations are synchronous transactions:
store.mit('increment')
// any state change that the "increment" mutation may cause
// should be done at this moment.
To handle asynchronous operations, let's introduce Actions.
That's why you should have a structure like this:
export const mutations = {
ADD_EVENT(state, event) {
state.events.push(event)
},
SET_EVENTS(state, events) {
state.events = events
},
SET_EVENTS_TOTAL(state, eventsTotal) {
state.eventsTotal = eventsTotal
},
SET_EVENT(state, event) {
state.event = event
}
}
export const actions = {
createEvent({ mit, dispatch }, event) {
return EventService.postEvent(event)
.then(() => {
mit('ADD_EVENT', event)
mit('SET_EVENT', event)
const notification = {
type: 'success',
message: 'Your event has been created!'
}
dispatch('notification/add', notification, { root: true })
})
.catch(error => {
const notification = {
type: 'error',
message: 'There was a problem creating your event: ' + error.message
}
dispatch('notification/add', notification, { root: true })
throw error
})
}
Check also this video out by vuemastery even featured on the official vuex docs: https://www.vuemastery./courses/mastering-vuex/intro-to-vuex/