> For the complete documentation index, see [llms.txt](https://mclassdesigns.gitbook.io/js-journal/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mclassdesigns.gitbook.io/js-journal/master.md).

# Using Axios in Vuex Actions

![](/files/-LfTqqM0pBqibzppYOCq)

Axios is a promise based HTTP client and Vuex actions can return promises. Combining the two is simple but there are a few gotchas to look out for.

This article assumes you are familiar with Axios, Vuex, and JavaScript promises at least at a basic level. It does not cover any installation or setup steps. I do hope to improve these examples over time for greater clarity, so your feedback would be greatly appreciated!

### Example 1 - Basic Use

We'll begin with a basic example and build from there. First, we should note that by *returning* an Axios request from within a Vuex action we are returning a *promise object* to the dispatch call. This should be obvious since Axios is promise based.

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        // Returns a promise object to
        // the calling function (ex. 'dispatch()')
        return axios.get('/api')
        
    }
}
```

We can then use `then()` and `catch()` methods on our dispatch call to handle the resolved or rejected promise from Axios, respectively:

#### Dispatch

```javascript
store.dispatch('myAction').then(response => {

    // Axios returned Promise.resolve(response)
    
    console.log(response)
    
}).catch(response => {

    // Axios returned Promise.reject(error)
    // For example, the desired API endpoint
    // was not found (i.e. 404 response code)
    
    console.log(error)
    
}
```

Of course, the purpose of Vuex actions is to perform asynchronous operations and commit mutations to our Vuex store, not just to make HTTP requests, but we can build on this simple example and begin to understand how Axios' promise API can interact with our dispatch calls.

### Example 2 - Axios `then()` and `catch()` Handlers

We can also append `then()` and `catch()` handlers to the Axios request itself, like so:

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        return axios.get('/api').then(response => {
        
            // Axios promise is resolved
            
            console.log(response)
            
        }).catch(error => {
        
            // Axios promise is rejected
            
            console.log(error)
            
        })
        
    }
}
```

However, since Axios is now handling its settled promise in its own `then()` and `catch()` methods, our dispatch call will no longer receive it. The dispatch call now simply executes its `then()` method with an `undefined` argument without knowing if the Axios promise was resolved or rejected:

```javascript
store.dispatch('myAction').then(response => {

    // Called by default with response undefined
    
    console.log(response)
    
}).catch(error => {

    console.log(error)
    
}
```

### Example 3 - Returning Values from Axios `then()` and `catch()` Handlers

We can fix the `undefined` problem by simply returning the response and error from our Axios handlers to the dispatch call:

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        return axios.get('/api').then(response => {
        
            return response
            
        }).catch(error => {
        
            return error
            
        })
    }
}
```

While this *will* return `response` to the dispatch call's `then()` handler, it *will not* return `error` to the dispatch call's `catch()` handler. Instead, both `response` and `error` will be handled by `then()`:

#### Dispatch

```javascript
store.dispatch('myAction').then(response => {

    // Receives both response
    // and error from Axios
    
    console.log(response)
    
}).catch(response => {
    
    // Will never be called
    
    console.log(error)
}
```

The reason for this is that simply *returning* a value from within a `then()` or `catch()` handler effectively returns `Promise.resolve(<value>)` to the calling function or to any subsequent, chained `then()` and `catch()` methods. In other words, our action really looks like this behind the scenes:

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        return axios.get('/api').then(response => {
        
            return Promise.resolve(response)
            
        }).catch(error => {
        
            return Promise.resolve(error)
            
        })
    }
}
```

This explains why our Axios error is handled by our dispatch call's `then()` method and not its `catch()` method; it believes the Axios promise was *resolved*. This is the default behaviour of a JavaScript promise and is not an Axios-specific feature.

{% hint style="info" %}
&#x20;When a value is simply returned from within a `then()` or `catch()` handler, it will effectively return `Promise.resolve(<value>)`.
{% endhint %}

### Example 4 - Catching the Rejected Axios Promise with Dispatch `catch()` Handler

We can catch the Axios rejected promise in our dispatch call's `catch()` handler by using the `Promise.reject(<value>)` method:

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        return axios.get('/api').then(response => {
        
            return response
            
        }).catch(error => {
        
            return Promise.reject(error)
            
        })
    }
}
```

#### Dispatch

```javascript
store.dispatch('myAction').then(response => {

    console.log(response)
    
}).catch(response => {

    // Now receives error from Axios

    console.log(error)
    
}
```

In fact, we could also have used `Promise.resolve(<value>)` in the Axios `then()` return statement, but it is not necessary for the reason explained in example 3:

#### Vuex Action

```javascript
actions: {
    myAction() {
        return axios.get('/api').then(response => {
        
            // Not necessary since it's equivalent
            // to simply 'return response'
            return Promise.resolve(response)
            
        }).catch(error => {
        
            return Promise.reject(error)
            
        })
    }
}
```

### Example 5 - Synchronous Operations in Axios `then()` Handler

As expected, any number of *synchronous* operations within the Axios `then()` handler will execute *before* the promise is resolved. In this example, a synchronous timer delays the response to the dispatch call:

#### Vuex Action

```javascript
actions: {
    myAction() {
    
        return axios.get('/api').then(response => {

            // Synchronous timer
            let delayFunc = function wait(ms) {
                var start = Date.now(),
                now = start;
                while (now - start < ms) {
                    now = Date.now();
                }
            }

            delayFunc(5000)

            return response

        }).catch(error => {
        
            return Promise.reject(error)
            
        })
    }
}
```

#### Dispatch

```javascript
store.dispatch('myAction').then(response => {

    // Called after 5000 milliseconds
    
    console.log(response)
    
}).catch(error => {

    console.log(error)
    
}
```

### Example 6 - Asynchronous Operations in Axios `then()` Handler

Also as expected, *asynchronous* operations within the Axios `then()` handler will not delay the promise from being resolved:

#### Vuex Action

```javascript
actions: {
    myAction() {
        return axios.get('/api').then(response => {

            // Asynchronous timer
            setTimeout(() => {
                console.log("Time's up!")
            }, 5000)

            return response

        }).catch(error => {
        
            return Promise.reject(error)
            
        })
    }
}
```

#### Dispatch

```javascript
store.dispatch('myAction').then(response => {
    
    // Called without waiting for setTimeout
    
    console.log(response)
    
}).catch(error => {

    console.log(error)
    
}
```

We'll need to consider examples 5 and 6 when building more complex, interdependent actions that dispatch other actions and make Axios requests. Since Vuex actions and Axios requests are all asynchronous, this can get a little tricky. We'll look at that in the next chapter.
