Ukpai Ugochi I am a female Nigerian with a Bachelor's degree in Marine engineering and Bootcamp certificates in Software development. I'm a full stack JavaScript developer (MEVN) stack. I love to share knowledge about my transition from marine engineering to software development in the form of writing, to encourage people who love software development and don't know where to begin. I also contribute to FOSS in my free time.

How to consume APIs with Vuex and Axios

7 min read 2105

Vuex API Axios Feature Image

An application programming interface (API) is a set of programming standards for accessing an application. This means that with an API, your backend and frontend applications can communicate with each other without the knowledge of the user.

“Consuming” an API means to receive requests and send responses via an API. In this article, you’ll learn how to consume APIs from a server using Vuex and Axios.

Introducing Axios and Vuex

Some frameworks, such as Angular 2, JQuery, and, until version 2.0, Vue.js, come with built-in HTTP APIs. In Vue.js 2.0, the developers decided that the built-in HTTP client module, Vue-resource, was no longer essential and could be replaced by third-party libraries. Now, the most recommended library is Axios.

Axios is a flexible HTTP client library that uses promises by default and runs on both the client and the server, which makes it appropriate for fetching data during server-side rendering. It’s easy to use with Vue.js.

Passing props can be difficult or almost impossible for deeply nested components. It can be tempting to use direct parent/child instance references or try to mutate and synchronize multiple copies of the state via events. Neither of these options are recommended because they may lead to unmaintainable code and bugs.

Vuex is a state management pattern and library for Vue.js applications. It serves as a centralized store for all the components in an application.

components state management actions and mutations

When to use Vuex

If you have never built a large-scale single page application (SPA), using Vuex may feel too complicated and unnecessary. But if you are building a medium- to large-scale SPA, chances are you have run into situations that make you think about how to better handle state and share state between components. If so, Vuex is the right tool for you!

Why you should use Vuex

Typically, you’ll want to use Vuex:

  • If your components need to share and update state
  • Because Vuex provides a single source of truth for data/state
  • Because there’s no need to pass events from one component and down through multiple components when you have state management
  • Because global state is reactive, which means altering state allows it to be updated in every other component using it

Understanding state management and the Vuex state management pattern

State management is the management of the state of the application or, more importantly, the data that should be presented to the user at any given time.

We made a custom demo for .
No really. Click here to check it out.

In an SPA like Vue.js, multiple components may, at any given time, interact with and change the data before sending it back to the server. Therefore, developers need a way to manage these changes — “the state” — which can be done with Vuex state management.

Vuex is a state management pattern that lets you extract shared state out of components, manage it in a global singleton, and allow components access to the state or trigger actions, no matter where they are in the tree.

How to set up the simplest Vuex store structure

You’ll need Vue CLI to create your Vue app. If you don’t have Vue CLI installed already, run the following in your terminal:

npm install -g @vue/cli

To see if Vue CLI is already installed on your system, execute the code below. A Vue version should appear if Vue is already installed.

vue --version
2.9.6

Now, create a Vue project by running the following code in your terminal:

/** if you want to create the vue project in the folder you
are currently on, use this code**/
vue create .

/**if you want to create a new folder for your vue app,
you should use this code**/
vue create myApp

/**if you are using Vue CLI version lesser than 3.0 use this code.**/
vue-init webpack myApp

Next, answer the questions as shown in the image below to create your Vue app:Consuming an API with Vuex and Axios

Then, install dependencies required for the project with the following codes:

/** to install vuex store for the project**/
npm install vuex

/**to install axios for handling http requests**/
npm install axios

Set up a simple Vuex store structure

First, create a folder in your src folder and name it store. In your store folder, create a file and name it index.js.

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       └── index.js        # where we assemble modules and export the store

Next, in your store/index.js file, input the following code:

// import dependency to handle HTTP request to our back end
import axios from 'axios'

//to handle state
const state = {}

//to handle state
const getters = {}

//to handle actions
const actions = {}

//to handle mutations
const mutations = {}

//export store module
export default {
    state,
    getters,
    actions,
    mutations
}
/** we have just created a boiler plate for our vuex store module**/

Register your store by adding the following codes to your main.js file:

//add this line to your main.js file
import store from './store'

new Vue({
//add this line to your main.js file
store,
render: h => h(App)
})
//other lines have already been added to your main.js file by default

Vuex actions and mutations explained

In Vuex, actions commit mutations instead of mutating the state. This means that while mutations can alter or change states, actions perpetuate the change. Actions can contain arbitrary asynchronous operations, meaning operations don’t need to be executed in sequence and the code doesn’t have to wait for an operation to execute; your program can continue to run.

Actions are triggered with the store.dispatch method and can be dispatched in components with this.$store.dispatch('xxx'). You can also use the mapActions helper, which maps component methods to store.dispatch.

Because actions commit mutations, Vuex state needs to be changed, but it can only be changed by committing a mutation. Vuex mutations each have a string type and a handler function. The handler function is where we alter or change the state, and it will receive the state as the first argument.

Keep in mind that mutation handler functions must be synchronous, and that you can commit mutations in components with this.$store.commit('xxx'), or use the mapMutations helper, which maps component methods to store.commit.

To understand what mutations and actions are and how they are used, we’ll register a simple mutation that will consume API from JSONplaceholder (fake online REST API for testing and prototyping):

// import dependency to handle HTTP request to our back end
import axios from 'axios'
import Vuex from 'vuex'
import Vue from 'vue'

//load Vuex
Vue.use(Vuex);

//to handle state
const state = {
posts: []
}

//to handle state
const getters = {}

//to handle actions
const actions = {
getPosts({ commit }) {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
commit('SET_POSTS', response.data)
})
}
}

//to handle mutations
const mutations = {
SET_POSTS(state, posts) {
state.posts = posts
}
}

//export store module
export default new Vuex.Store({
state,
getters,
actions,
mutations
})

Now, create a new component named myStore and paste the following code into it:

<template>
  <div class="hello">
    <h1>{{ msg }}/h1>
    <div v-for='post in posts' :key='post.id'>
  <h3>Post Title: /h3>  {{post.title}}
      <h3>Post Body: /h3>{{post.body}}
    </div>
    <h2>Essential Links/h2>
  </div>
</template>

<script>
export default {
  name: 'myStore',
  data () {
    return {
      msg: 'Welcome to my Vuex Store'
    }
  },
  computed: {
    posts() {
    return this.$store.state.posts
    }
  },
  mounted() {
    this.$store.dispatch("getPosts");
  }
}
</script>

Serve your application by executing npm run dev on your terminal, then navigate to localhost:8080/myStore to see your Vuex application.

Vuex Store application created

Vuex getters explained

In the course of passing state among components, you may need to enumerate derived state based on store state. With Vuex, getters do not actually store a value. Instead, they retrieve and set Vuex state indirectly.

Vuex getters receive the state as their first argument and can receive other getters as the second argument. MapGetters is a helper that maps store getters to local computed properties.

To understand what a getter is and how to use it, we are going to compute a derived state based on our store state by hot-coding our state:

// import dependency to handle HTTP request to our back end
import Vuex from 'vuex'
import Vue from 'vue'

//load Vuex
Vue.use(Vuex);

//to handle state
const state = {
products: [
{
id: 1,
title: 'Shirt',
price: '$40'
},
{
id: 2,
title: 'Trouser',
price: '$10'
},
]
}

//to handle state
const getters = {
allProducts: (state) => state.products
}

//to handle actions
const actions = {}

//to handle mutations
const mutations = {}

//export store module
export default new Vuex.Store({
state,
getters,
actions,
mutations
})

Next, in your "myStore" folder, paste the following code:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <div v-for="product in products" :key="product.id">
      {{product.title}}, {{product.price}}
      </div>
  </div>
</template>

<script>
/*
import { mapGetters } from 'vuex'; //This is 
another method for mapGetters Helper
*/
export default {
  name: "myStore",
  data() {
    return {
      msg: "Welcome to my Vuex Store Getter example",
    };
  },
  computed: {
    products() {
      return this.$store.getters.allProducts;
    },
  },
  /* 
  computed: mapGetters(['allProducts']) //This is 
another method for mapGetters Helper
  */
};
</script>
Serve your application by executing npm run dev on your terminal, then navigate to localhost:8080/myStore:

 

Vuex store getter example

Consuming APIs with Vuex and Axios using actions, mutations, state, and getters

To understand properly how to create a Vuex store and consume APIs with Axios using Vuex actions, state, mutations, and getters, we’ll create a simple Vuex application that fetches user information from our fake JSON backend:

// import dependency to handle HTTP request to our back end
import axios from 'axios'
import Vuex from 'vuex'
import Vue from 'vue'

//load Vuex
Vue.use(Vuex);

//to handle state
const state = {
users: []
}

//to handle state
const getters = {
allUsers: (state) => state.users
}

//to handle actions
const actions = {
getUsers({ commit }) {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
commit('SET_USERS', response.data)
})
}
}

//to handle mutations
const mutations = {
SET_USERS(state, users) {
state.users = users
}
}

//export store module
export default new Vuex.Store({
state,
getters,
actions,
mutations
})

In your myStore folder, paste the following code:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h1>Made By Getters</h1>
  <div v-for='gettersuser in gettersusers' :key='gettersuser.id'>
    {{gettersuser.id}} {{gettersuser.name}} {{gettersuser.address}}
    </div>
    <h1>Made By Actions</h1>
  <div v-for='user in users' :key='user.id'>
    {{user.id}} {{user.name}} {{user.address}}
    </div>
  </div>
</template>

<script>
export default {
  name: 'myStore',
  data () {
    return {
      msg: 'Welcome to my Vuex Store'
    }
  },
  computed: {
    gettersusers() {
    return this.$store.getters.allUsers
    },
    users() {
    return this.$store.state.users
    }
  },
  mounted() {
    this.$store.dispatch("getUsers");
  }
}
</script>

Now, serve your application by executing npm run dev on your terminal and again navigate to localhost:8080/myStore to see your first Vuex application created.

vuex store getters and actions

 

Different Vuex store structures

Below is the simplest Vuex store structure, where actions, getters, state, and mutations are called and exported in the index.js file.

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       └── index.js         # where we assemble modules and export the store

As your application becomes larger, there may be need to separate our actions, mutations, getters, and state modules into their different files.

├── index.html
└── src
    ├── components
    ├── App.vue
    └──store
       ├── index.js        # where we assemble modules and export the
       ├── actions.js      # root actions
       ├── mutations.js    # root mutation
       ├── getters.js      # root getters
       └── state

Because we’re using a single state tree, all states in our application are contained inside one large object. This isn’t ideal because our application grows as our actions, mutations, and state become larger, making it possible for the store to become even larger, so much so that we may not be able to keep up with it.

A great solution is to group our store into modules. Each module can contain its own state, mutations, actions, and getters, and they can even contain nested modules.

├── index.html
├── main.js
├── api
│   └── ... # abstractions for making API requests
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # where we assemble modules and export the store
    ├── actions.js        # root actions
    ├── mutations.js      # root mutations
    └── modules
        ├── cart.js       # cart module
        └── products.js

Conclusion

In this tutorial, we’ve looked at what state management is and why you need Vuex for your Vue applications. We’ve also reviewed what the Vuex store comprises and what actions, mutations, getters, and state are in Vuex.

In addition, we created a simple Vue application to demonstrate Vuex, as well as learned different Vuex store structures so you can decide which one is best for your application.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Experience your Vue apps exactly how a user does

    Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

    LogRocket is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

    The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

    Modernize how you debug your Vue apps - .

    Ukpai Ugochi I am a female Nigerian with a Bachelor's degree in Marine engineering and Bootcamp certificates in Software development. I'm a full stack JavaScript developer (MEVN) stack. I love to share knowledge about my transition from marine engineering to software development in the form of writing, to encourage people who love software development and don't know where to begin. I also contribute to FOSS in my free time.

    Leave a Reply