How to save data to your API using Vuex
I talked before about how to query your back-end API from Vuex, but that was mainly centered on getting data. What happens when you want to save data to a back-end API after it is updated or added in the Vuex store? What’s the best, most efficient way to accomplish this?
As I talked about in my article on the purpose of Vuex, Vuex is not meant to act as a central datastore. It’s not a permanent place to keep data by any means. If a user navigates away from the application or the user’s browser crashes, everything that was stored in Vuex will be gone. For this reason, we never want to store something in Vuex and tell the user it has changed if the real data (the data in the back-end database) has not actually changed. We want to make sure that data changes first before updating the UI and possibly misleading a user.
So, how can we accomplish this? Again, I have taken some inspiration from the Vue Real World project by gothinkster. I think that the way they handle it is pretty good. It assumes a couple of things:
- When data changes in the application, always send it to the back-end.
- Don’t save changed data in the Vuex store. Instead, get it again from the back-end.
Sending data to the back-end API using Actions
One of the requirements of using Vuex to work with a back-end API is that all changes to data should not go through mutations, but instead through actions. I talked at one point about why you might want to make logic changes to data in Vuex through actions and calling APIs certainly falls under the category “logic”.
So all data manipulation that needs to be saved to a back-end should happen through Actions. As an example, let’s imagine that our application allows adding a new user to a system that we are creating. When the form is submitted for a new user, what we want to do is have that passed to a Vuex action from the component:
methods: {
submitUser() {
this.$store.dispatch('saveUser', this.user);
}
}
Then, in Vuex action, you can save that data by calling the back-end API:
actions: {
saveUser(context, user) {
Vue.axios.post('users', user);
}
}
And then, once the promise resolves, make a call to load in the users again from the back-end:
actions: {
saveUser(context, user) {
Vue.axios.post('users', user).then(result => {
context.dispatch('loadUsers');
});
},
loadUsers({commit}) {
...
}
}
So the flow here becomes:
- Call the action from the component to save the new user
- In the action, call the API to save the user data to the back-end
- After the back-end says everything is good, get the new data from the back-end
It might seem strange to get the data that we just saved to the back-end, but it solves a couple of pressing issues.
- The back-end should be in charge of final validation on all data. By getting the data from the back-end after saving it there, we ensure that the data is fully validated before we set that data in Vuex for the components to use.
- The back-end may need to change or format the data or set unique ids on the data. By passing the data to the back-end and then getting it back from the back-end, we can be sure the id and other data will be populated and that we’ll have it in the front-end.
One of our main goals should be to make sure our data stays in sync with the back-end. This is a good approach to make sure that happens.