Skip to content

Instantly share code, notes, and snippets.

@lakhbawa
Created August 11, 2020 13:45
Show Gist options
  • Save lakhbawa/64752137a6d6ab2e6c411c9629d44a66 to your computer and use it in GitHub Desktop.
Save lakhbawa/64752137a6d6ab2e6c411c9629d44a66 to your computer and use it in GitHub Desktop.
Vuex Design for better maintainability and reusability
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 () {
})
// 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,
}
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,
}
// 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