Reduce async boilerplate code generating Vuex modules. Compatible with Vue 2.x
npm install @liqueflies/vuex-async-module --save
# or
yarn add @liqueflies/vuex-async-module
vuex-async-module
generates Vuex Modules reducing boilerplate for asynchronous request, inspired by this post of Lachlan Miller.
The workflow for a successful asynchronous request should be like:
state = {
isPending: true // pending... show a spinner
statusCode: null,
data: null,
errors: null
}
// some time later... the ajax request is successful
state = {
isPending: false, // no longer pending
statusCode: 200, // success code 200
data: {...}, // response data
errors: null // no errors
}
Standard Vuex code should write also types
, actions
, mutations
, and getters
for each async action.
We can notice that in many cases we will write the same code over and over again.
vuex-async-module
will scaffold this code for you.
import getAsyncModule from '@liqueflies/vuex-async-module'
export default new Vuex.Store({
state, // your state,
actions, // your actions
getters, // your getters
mutations, // your mutations
modules: {
// use a promise async library that return data and status on response
movies: getAsyncModule({ xhr: axios.get })
}
})
and then in your .vue
import { asyncModuleMixin } from '@liqueflies/vuex-async-module'
export default {
// component `name` is the same as module name
name: 'movies',
// include mixin for automatically bind two computed props:
// [componentName]RequestIsPending i.e moviesRequestIsPending
// [componentName] i.e. movies
// and a method!
// getAsync[componentName] i.e. getAsyncMovies(url, forceUpdate)
mixins: [asyncModuleMixin],
// place this call where you prefer, here we will use `beforeMount`
beforeMount () {
this.getAsyncMovies({ url: 'https://ghibliapi.herokuapp.com/films' })
}
}
and in the template
<div v-if="moviesRequestIsPending" />
<ul v-else>
<li v-for="movie in movies" :key="movie.id">
<h2> {{ movie.title }} - {{ movie.release_date }} </h2>
</li>
</ul>
vuex-async-module
has only one constrain: component
name must be the same of module
name.
vuex-async-module
mixin adds two computed
properties:
- [
componentName
]RequestIsPending - i.emoviesRequestIsPending
- [
componentName
] - i.e.movies
and a method
- getAsync[
componentName
] i.e. getAsyncMovies
getAsync
expects to receive the url for the ajax call, and a boolean parameter to force the update of the previous fetched data.
And the job is done!
Thanks to Marco Solazzi and Giovanni Rodighiero.
Copyright (c) 2017 Lorenzo Girardi