Skip to main content
  1. Posts/

How to query your API using Vuex in your Vue application

·866 words·5 mins
Joe Erickson
Author
Joe Erickson
Senior software developer specializing in web development, AI, and helping others learn to code.

Once you start using Vuex to manage the shared data of your Vue application, it becomes less clear on where or how to call your back-end API. I think everyone starts out making API calls in the created function of your component. But that doesn’t scale past a handful of components. Then, they end up loading in the same data over and over again and each component has it’s own copy, which is impossible to keep in sync. You lose the efficiency of having one part of the system in control of the data when you do that and on a larger application, this very quickly falls apart.

You could try to share the data pool using a Vuex store with every component calling APIs and shoving the data into Vuex, but then every component is sharing API logic and unit testing becomes pretty impossible to do. Components shouldn’t really be messing with outside resources that much and should instead focus on their one area of responsibility. Otherwise, you get maintenance hell.

There seem to be a million ways to do this, but a simple one I’m going to show now is one that I have liked and have seen in other projects, too.

The responsibility of the data for the application rests squarely on Vuex and so I will show how Vuex can handle all back-end data interactions as well. This will keep our data responsibilities all in one place.

I have a bare bones sample project on CodeSandbox here, if you want to check it out: https://codesandbox.io/s/example-api-call-from-vuex-t7zxw

Making the API call
#

Vuex has two sections where logic can be kept; actions and mutations. I’ve talked before in Understanding data flow in Vuex about what the difference is between these two sections but we’re going to use them together to perform our API call.

First, create a new state field for the user information, which will be coming in as an array of objects, but that we can just set to an empty array to start with:

state: {
  users: []
},

Then we want to set up a simple mutation (all mutations should be simple) that will take a new set of users and set them to the state:

mutations: {
  SAVE_USERS(state, users) {
    state.users = users;
  }
}

We’re now ready for the actual API call. I’m going to use Axios and Vue-Axios for this call, which is a library that makes API calls super simple and sane.

First, I’ll set the default base URL to the API1:

Vue.axios.defaults.baseURL = "https://jsonplaceholder.typicode.com/";

Then we can set up an action to actually make the API call. Why an action? Because this is a call that will do some logic and will take time (network calls always take an unknown amount of time). Actions are meant to be asynchronous while mutations should happen as near to instantly as possible.

So we make an action that makes the API call and then calls the mutation with to set the data once it’s done.

actions: {
  loadUsers({commit}) {
    Vue.axios.get('users').then(result => {
      commit('SAVE_USERS', result.data);
    }).catch(error => {
      throw new Error(`API ${error}`);
    });
  }
},

This Vuex store not only handles the local data store like it should, it also has all the logic needed to refresh the data store from the back-end.

Using the Vuex store in a component
#

How should this back-end aware Vuex store be used in a component? Most everything will be the same as usual. We’ll create computed properties that will link to the Vuex’s state information:

computed: {
  users() {
    return this.$store.state.users;
  }
},

or, using mapState()

computed: mapState(['users']),

The trick is that the action in the Vuex store to load in the users, loadUsers(), will not magically call itself. So a component will do that itself when it is created:

created() {
  this.$store.dispatch('loadUsers');
}

This doesn’t do anything to the component except let the Vuex store know that it wants some user data. Once the user data loads into the Vuex store, the computed mapping to that state is triggered and the component will show the new data.

If there were multiple back-end endpoints, as there would be in any application that wasn’t super simple, then a component would just trigger a load for data that it needed. There is no need to load in everything from the back-end all at once if it’s not needed by any of the components that are on the page.

If you want to see this in action, feel free to look at the CodeSandbox I set up called Example API call from Vuex.

This is one way to handle API calls in a Vue application and one that is shown in the Real World Vue project on Github. I like this approach in that it keeps all the data handling within the sphere of Vuex and let’s the components be both focused on their front-end presentation duties and unit testable since they aren’t connecting to any system outside of themselves except the easily mockable Vuex store.


  1. This would usually go in an environment variable. Hard coding it here merely as an example. Here, we’re using data from a faked API over at JSON Placeholder↩︎

Related

Should you always use getters in Vuex?

·1166 words·6 mins
One of the questions that comes up time and again concerning Vuex is “Do I always use a getter when accessing data? Or can I directly access the raw state?” It’s one of those things you hear about that you should do, but no one seems to really explain why. And do you really need to create a getter for every single piece of data that you put in the store? Isn’t that just a bunch of unneeded boilerplate and duplication?

Loading dynamic images in a Vue Component

·541 words·3 mins
When I first started using Vue, one thing I got continually wrong was how to load an image into a Vue component dynamically. At first, I found that using an absolute URL worked, but that was only useful if I was storing the images on a CDN or other external site. If I included the images in my project, as either lightweight icons or static images, then using an absolute URL, with hostname and all, didn’t really work. What about when I wanted to test some new images locally or on a dev server? Linking directly to the images in production just wasn’t going to cut it.

Understanding data flow in Vuex

·646 words·4 mins
If you’re like me, when you first ran into Vuex, you probably wondered “How the heck does this work?” It’s not immediately obvious how these types of state management systems work, especially if you come from an SQL background. And do I even need it? In fact, the Vuex documentation has a quote that sums it up pretty well:

Thank you for seeing my talk at JavaScript and Friends!

·145 words·1 min
Thank you so much for coming out and seeing my talk at the JavaScript and Friends conference (or the video later on). I wanted to give you some extra links to some of the things that I talked about.