Created
August 11, 2020 13:45
-
-
Save lakhbawa/64752137a6d6ab2e6c411c9629d44a66 to your computer and use it in GitHub Desktop.
Vuex Design for better maintainability and reusability
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this.$store | |
.dispatch('modules/auth/switchAccount', { | |
queryParams: { | |
new_account_type: newAccountType, | |
}, | |
}) | |
.then((response) => { | |
if (response.success) { | |
this.$buefy.toast.open({ | |
message: response.message, | |
type: 'is-success', | |
}) | |
// alert('status changed success fully') | |
} | |
}) | |
.catch((error) => { | |
}) | |
.finally(function () { | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// state mutations and actions defined here will get added to every module file | |
// store gets automaticly created form modules | |
// https://nuxtjs.org/guide/vuex-store#modules-mode | |
export const state = () => ({ | |
loading: false, | |
}) | |
export const mutations = { | |
SET_LOADING: (state, value) => (state.loading = value), | |
} | |
export const actions = { | |
} | |
export const getters = { | |
getLoadingState: (state) => state.loading, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import VuexUtils from '~/utils/VuexUtils' | |
const state = () => ({ | |
// Pre-fill one row with an | |
// empty `Contact` model. | |
experience: {}, | |
query: { | |
page: 1, | |
}, | |
}) | |
const getters = { | |
getExperience: (state) => state.experience, | |
} | |
const mutations = { | |
SET_EXPERIENCE: (state, payload) => { | |
state.experience = payload | |
}, | |
} | |
const actions = { | |
submitExperienceAction(context, config) { | |
config = VuexUtils.configAdapter({ | |
config, | |
getters: context.getters, | |
includeQuery: false, | |
}) | |
const defaultValues = { | |
url: '/experiencess', | |
queryParams: {}, | |
allParams: {}, // also includes additional params such as page no. sort etc | |
} | |
config = Object.assign(defaultValues, config) | |
return VuexUtils.postRequestWithMediaWrapper({ | |
fetcher: this.$axios, | |
url: config.url, | |
module: 'experience', | |
context, | |
params: config.allParams, | |
commitableMutations: [{ SET_EXPERIENCE: 'response.data.result' }], | |
}) | |
}, | |
} | |
export default { | |
actions, | |
mutations, | |
state, | |
getters, | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// const defaultValues = { | |
// url: null, // url to the Form action | |
// module: null, // name of vuex module | |
// context: null, | |
// fetcher: null, // axios instance, This is neccesary as Axios instnace may have tokens or heads or something which does not come with fresh instance | |
// params: {}, // parameters GET or POST | |
// commitableMutations: [], // Example [{SET_APPLICATIONS: 'response.data.result'}] | |
// // reject: null, // required when its being called within Promise | |
// // resolve: null, // likewise | |
// callback: null, | |
// } | |
export default { | |
getRequestWrapper(config) { | |
return this.requestWrapper(config, 'get') | |
}, | |
postRequestWrapper(config) { | |
return this.requestWrapper(config, 'post') | |
}, | |
postRequestWithMediaWrapper(config) { | |
// making this separate function can be useful in making progress bar and other things | |
return this.requestWrapper(config, 'post_with_media') | |
}, | |
requestWrapper(config, type) { | |
/* | |
This is special wrapper to abstract the requests inside vuex actions | |
This wrapper takes all the necessary resources within config variable and make the action on them, | |
This can take mutation names and correspoinding response paramter and commit them, | |
/ | |
*/ | |
if (config.fetcher == null || config.url == null) { | |
throw new Error('Some Parameters were Missing') | |
} | |
if (!config.context.state.loading) { | |
return new Promise((resolve, reject) => { | |
// using return is essential here to use that method in asyncData function | |
if (!config.context.state.loading) { | |
config.context.commit('SET_LOADING', true, { root: true }) | |
let request | |
if (type === 'get') { | |
request = config.fetcher.get(config.url, { | |
params: config.params, | |
}) | |
} else if (type === 'post_with_media') { | |
request = config.fetcher.post(config.url, config.params, { | |
headers: { | |
'Content-Type': 'multipart/form-data', | |
}, | |
}) | |
} else if (type === 'post') { | |
request = config.fetcher.post(config.url, config.params) | |
} else { | |
throw new Error('Request type unknown') | |
} | |
// console.log(config.commitableMutations) | |
request | |
.then((response) => { | |
if (!response) { | |
reject(new Error('Response is Undefined, Not sure why')) | |
} | |
if (!response.data.success) { | |
reject(response.data.message) | |
} | |
if (config.commitableMutations.length) { | |
for (const mutation of config.commitableMutations) { | |
for (const property in mutation) { | |
// iterating over object properties | |
// just to satify IDE | |
if ( | |
Object.prototype.hasOwnProperty.call(mutation, property) | |
) { | |
// console.log(`${property}: ${mutation[property]}`) | |
// eslint-disable-next-line no-eval | |
if (eval(mutation[property]) != null) { | |
let commitValueString | |
if (mutation[property] == null) { | |
commitValueString = 'response.data.result' | |
} else { | |
commitValueString = mutation[property] | |
} | |
// eslint-disable-next-line no-eval | |
config.context.commit( | |
'modules/' + config.module + '/' + property, | |
// eslint-disable-next-line no-eval | |
eval(commitValueString), | |
{ root: true } | |
) | |
if (config.callback) { | |
config.callback() | |
} | |
} else { | |
config.context.commit( | |
'modules/' + config.module + '/' + property, | |
// eslint-disable-next-line no-eval | |
[], | |
{ root: true } | |
) | |
} | |
} | |
} | |
} | |
} | |
resolve(response.data) | |
}) | |
.catch((error) => { | |
reject(error) | |
}) | |
.finally(() => { | |
config.context.commit('SET_LOADING', false, { root: true }) | |
}) | |
} | |
}) | |
} | |
}, | |
configAdapter({ config, getters, includeQuery }) { | |
// includeQuery defines if we need to include query params such as page and sort etc | |
// used in vuex actions | |
if (typeof config === 'undefined') { | |
config = {} | |
let essentialParams | |
if (typeof includeQuery !== 'undefined' && includeQuery === false) { | |
} else if (typeof getters.getQuery !== 'undefined') { | |
essentialParams = getters.getQuery | |
} | |
config.allParams = { ...essentialParams } | |
} else if ( | |
typeof config.formData !== 'undefined' && | |
config.formData instanceof FormData | |
) { | |
// backward compatiabiltiy | |
if (typeof includeQuery !== 'undefined' && includeQuery === false) { | |
} else if (typeof getters.getQuery !== 'undefined') { | |
Object.entries(getters.getQuery).map((item) => { | |
// eslint-disable-next-line no-eval | |
config.formData.append(item[0], item[1]) | |
}) | |
} | |
config.queryParams = config.formData | |
config.allParams = config.queryParams | |
} else if (typeof config === 'string') { | |
const urlAsConfig = config | |
config = {} | |
config.url = urlAsConfig | |
} else { | |
config.allParams = config.queryParams | |
let essentialParams | |
if (typeof includeQuery !== 'undefined' && includeQuery === false) { | |
} else if (typeof getters.getQuery !== 'undefined') { | |
essentialParams = getters.getQuery | |
} | |
config.allParams = { ...essentialParams, ...config.queryParams } | |
} | |
return config | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment