1
votes

I have a vuejs component and a vuex store.

I would like to send data from vue component 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 component
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 ({ commit, rootState }, product) => {
    const userProductDb = new UserProductsDB(
        rootState.authentication.user.id
    );

    const createdProduct = await userProductDb.create(product);
    commit("addProduct", createdProduct);
 },
 triggerAddProductAction: ({ dispatch, state, commit }) => {
    const post = state.newPost;
    dispatch("createUserProduct", post);
 }
}
2
You pass the data as the second parameter to dispatch, for example to pass a value of 1 use: this.$store.dispatch('createUserProduct', 1)Get Off My Lawn
yeah I understand, but does not helped melukas34tfd
const post = .. is empty and I don't know whylukas34tfd
I think it is because of the way you formatted the objectGet Off My Lawn
I tested different ways but each time the same errorlukas34tfd

2 Answers

3
votes

Your 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({ commit }, product) {
      commit("addProduct", product);
    }
  }
});

new Vue({
  el: "#app",
  store,
  mounted() {
    this.$store.dispatch('createUserProduct', 1)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.0/vuex.min.js"></script>
<div id="app"></div>
1
votes

I think one of the main problems here is actually that you call mutations directly in your component. 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 combined 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.commit('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({ commit, dispatch }, event) {
    return EventService.postEvent(event)
      .then(() => {
        commit('ADD_EVENT', event)
        commit('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.com/courses/mastering-vuex/intro-to-vuex/