Donnie Donnie - 2 months ago 30
Javascript Question

Dispatch mutations from service file

I have an

ApiService()
that I'm abstracting my API calls into. I'd like to
dispatch('SET_BUSY')
and
dispatch('SET_NOT_BUSY')
app-level mutations from within the
service, but I get the following error:

TypeError: dispatch is not a function. (In 'dispatch('SET_BUSY')', 'dispatch' is undefined)





/vuex/actions.js

import { ApiService } from './services';

export const setAppMode = function ({ dispatch }) {
ApiService({
noun: 'Application',
verb: 'GetMode'
}, response => {
dispatch('SET_APP_MODE', response.Data.mode);
},
dispatch);
};


/vuex/services.js

import Vue from 'vue';

export const ApiService = (options = {}, callback, dispatch) => {
let endpoint = 'localhost/api/index.php';
let parameters = options.data;

dispatch('SET_BUSY');

Vue.http.post(endpoint, parameters, []).then((promise) => {
return promise.text();
}, (promise) => {
return promise.text();
}).then(response => {
response = JSON.parse(response);

dispatch('SET_NOT_BUSY');

if (response.Result === 'ERROR') {
console.log('ERROR: ' + response.Error.Message);
}

callback(response);
});
};

Answer

An action function expects the store instance as the first parameter. This is usually done by Vuex automatically.

When using an action in a Vue instance, the way to accomplish it in Vuex 1 is as follows:

import { setAppMode } from './actions'

new Vue({
  vuex: {
    actions: {
      setAppMode
    }
  }
})

Now you can use this.setAppMode() and have the store automatically available as first argument.

Note: you also need to set the storeproperty of the VM

import store from `./store`

// and inside the VM options:
{ 
    store: store
}

If store has not been set to the vm instance, you still can pass it as a parameter, manually:

this.setAppMode(store);
Comments