112

Is there a way for a dispatch/action to call a getter inside of it?

mutations: {
    setData(state, data) {
        state.data = data;
    }
}
actions: {
    sendDataToServer({ commit }, payload) {
        // call getter (data) and assign to variable
        // do async functions from the data returned
    }
},
getters: {
    getAppData: state => () => {
        return state.data;
    }
}

So what's the best practice here? Using the mutation to change the state and then get the state and pass it to action which will then execute the async function or do I need to restructure my implementation?

call mutation -> get the data via getter -> call action

OR

do it all on the action (do mutation on the action and do the action/async method without the need of the getter)?

The Bassman
  • 2,241
  • 5
  • 26
  • 38
  • 6
    In addition to commit, actions has default injected parameters which are `dispatch`, `getters` and `rootGetters`. So you can simply write; `sendDataToServer({ commit, getters }, payload)` to access getters. – Tugay İlik Aug 28 '18 at 08:49
  • 1
    @Tugayİlik You should make a answer, so we can upvote. – Shiva127 May 02 '19 at 09:46

5 Answers5

187

In addition to commit, actions has default injected parameters which are dispatch, getters and rootGetters. So you can simply write;

sendDataToServer({ commit, getters }, payload) to access getters.

Tugay İlik
  • 3,688
  • 1
  • 14
  • 21
45

You have access to getters inside an action:

getters: {
   getUser(state){
      return state.user
   }
}

actions : {
    myAction({ getters }){
       let user = getters.getUser
    }
}
Ahmad Mobaraki
  • 7,426
  • 5
  • 48
  • 69
17

In the action, you see the first parameter has {commit} in it. Similarly, you can pass {commit, state}. This way, you can directly access the state.data.

I think in your example, you would want to do the action because you can call the mutation from inside action itself using commit('setData').

The first parameter is there for you to use state and mutation as you prefer. Personally, I have only worked on projects where you do the action first and do mutation to store it in the app. For example, if I want to store a car info in the server somewhere, first I would do the action (and save it to remote db). Once I confirm that it saved in db, I would locally mutate in the store. This totally depends on case by case basis. But good thing is that you can mutate from inside the action

Sujil Maharjan
  • 1,307
  • 10
  • 12
  • Actually there can be a couple more mutations to be done, not only setData, I also want to updateData for example. On an insertion, I will call setData or on update call the updateData, actually what my action does is send the data to the server just to update the data of the server (the data also includes a jwt token) which will then check if the token is valid, if the token is invalid, redirect the user back to the first process which is insertion and the process repeats. So it's actually the opposite, the async method comes first before the mutation. What do you think? – The Bassman Aug 28 '18 at 02:04
  • What is the best flow for the scenario stated above? – The Bassman Aug 28 '18 at 02:05
  • Looks like you are dealing with the server first. So, if I am understanding it correctly, Async call the API -> if success, commit set/update. If not, make another API call and do the same step from the beginning. – Sujil Maharjan Aug 28 '18 at 02:11
  • 1
    Yes, that is correct sir.. I actually got what I need and that's from your solution which is to add a state after the commit `{ commit, state }`. Thanks! – The Bassman Aug 28 '18 at 02:31
9

Action handlers receive a context object which exposes the same set of methods/properties on the store instance, so you can call context.commit to commit a mutation, or access the state and getters via context.state and context.getters

   actions: {
            sendDataToServer(context, payload) {
                // context object contains state, commit, getters
                context.getters.getAppData
            }
        },

Refer docs: https://vuex.vuejs.org/guide/actions.html#dispatching-actions

Harshith J Poojary
  • 316
  • 10
  • 26
3

If you are using nuxt and isolated files in vuex, like this =

store -
      |
      |-- index.js
      |
      |-- store.js
      |
      |-- product.js

// store.js
export const getters = {
  getNameStore: state => state.getNameStore ? state.getNameStore : null
};

I want the getNameStore of the store.js into product.js

// product.js
export const actions = {
  setResultSearch({ commit, dispatch }, text) {
    console.log(
      'getNameStore',
      this.getters["store/getNameStore"]
  );
};

this.getters["store/getNameStore"]

Mm.Mirzaei.dev
  • 333
  • 3
  • 10