fbpx

Get Kanye West Quotes w/ Vue and Axios – Beginner’s Guide to APIs

Axios is one of the most popular HTTP request libraries for Javascript, and it’s commonly used to call APIs inside of Vue apps. 

In this article, we’re going to be making a Kanye West Quote Generator using Axios in a Vue 3 app. Not only are we going to get some deep inspiration from Ye himself, but we’re going to learn how to connect our Vue apps to APIs and even learn how to better organize your Vue project with reusable API calls. 

Rather watch this tutorial? Check out our YouTube video.

Let’s jump right into the code.

Setting Up Our First Basic HTTP Request

The first thing we have to do is install Axios into our project in the terminal 

npm install axios

Then, we can go inside of a Vue component and import axios like this.

<script>
import axios from 'axios'

export default {
  setup () {
  
  }
}
</script>

Next, inside our setup method let’s run axios.get with the URL of Kanye REST API to get a random quote.After, we can use a Promise.then to wait for the our request to give us a response.

<script>
import axios from 'axios'

export default {
  setup () {
     axios.get('https://api.kanye.rest/').then(response => {
        // handle response
     })
  }
}
</script>

Alright so now we’re getting a response from our API, but let’s go ahead and see what it actually is. To do this, we’ll store it as a ref called quote

<script>
import axios from 'axios'
import { ref } from 'vue'

export default {
  setup () {
     axios.get('https://api.kanye.rest/').then(response => {
        // handle response
        quote.value = response
     })
     return {
      quote
     }
  }
}
</script>

Finally, let’s print it up in our template in italics and surrounded by some quotes. And of course, we need some attribution on this quote.

<template>
  <div>
    <i>"{{ quote }}"</i>
    <p>- Kanye West</p>
  </div>
</template>

Alright – let’s check out what we have in our browser. 

We can see our quote here, but there’s all this extra information like the response code of our request. 

For our Kanye quote generator, we’re only really interested in this data.quote value – so back inside of our script section, let’s specify which property on response we want to access.

axios.get('https://api.kanye.rest/').then(response => {
        // handle response
        quote.value = response.data.quote
})

Alright, if we go back, we’ll see that we’re only getting the quote. Awesome.

Using Axios with async/await

Another way that we can use Axios in our Vue app is with an async/await pattern.

Inside setup, let’s start off by commenting out our current GET code and creating an asynchronous method called loadQuote. Inside, we can use our same axios.get method, but this time we want to use async to wait for it to finish and then store that result inside a constant called response

Then, once again, let’s set the value of quote

const loadQuote = async () => {
      const response = await KanyeAPI.getQuote()
      quote.value = response.data.quote
}

That’s it. If we look at our app, it works exactly the same, but in our code, we’re using the async/await pattern. 

Read Also:  When/Why to Use Vue Scoped Slots

Awesome.

Error Handling in  Axios

In the async-await pattern, we can add error handling by surrounding our API call with a try and catch. That’s it.

try {
        const response = await KanyeAPI.getQuote()
        quote.value = response.data.quote
} catch (err) {
        console.log(err)
}

With the original promises syntax, we can add a .catch after our API call to capture any errors coming from our request. 

axios.get('https://api.kanye.rest/')
      .then(response => {
        // handle response
        quote.value = response.data.quote
      }).catch(err => {
      console.log(err)
})

Sending a POST Request 

Now that we know how to send GET requests with Axios, let’s look at sending POST requests. 

To do this in this tutorial, we’re going to be using the JSONPlaceholder Mock API Calls

And if we look at their documentation, they give us a /posts POST request.

Okay – let’s make a button that will trigger our API call. In our template, let’s make a button that says “Create Post” and when it’s clicked, it calls a method called createPost.

<template>
  <div>
    <i>"{{ quote }}"</i>
    <p>- Kanye West</p>
    <p>
      <button @click="createPost">Create Post</button>
    </p>
  </div>
</template>

Alright – we can head down to our script, make this createPost method, and return it from setup.

In this method, similar to our GET request, we just have to say axios.post, pass in our URL, which is the https://jsonplaceholder.typicode.com/posts and then we can just copy and paste the placeholder data from their documentation.  

const createPost = () => {
      axios.post('https://jsonplaceholder.typicode.com/posts', JSON.stringify({
          title: 'foo',
          body: 'bar',
          userId: 1,
      })).then(response => {
        console.log(response)
      })
}

Alright – let’s try this out.

If we click our button, we’ll see that our console is logging a ton of information telling us that our post request was successful.

Awesome.

Pro Tip: Write Reusable API Calls with Axios

One tip that I use in my projects to help organize all of my api calls is to create a src/services folder that will contain my API calls.

These will have 2 types of files:

  • API.js – a file that will create an Axios instance with a defined baseURL that will be used for all routes
  • {specific functionality}API.js – more specific files that can be used to organize the api calls into reusable modules

This has several benefits. First, by creating one API.js file that creates the axios instances, it means that your base URL is set in one place – meaning that if you wanna toggle between the dev and prod servers, you only have to change your code in this file. 

So let’s create our services/API.js file and set our Axios baseURL to default to the Kanye REST API unless we pass in another value.

import axios from 'axios'

export default(url='https://api.kanye.rest') => {
    return axios.create({
        baseURL: url,
    })
}

And that’s all for that file, next let’s make a KanyeAPI.js file and import API from './API'. Here, we want to export different API calls.

Read Also:  Explaining the Vue Context Argument - A Composition API Tutorial

Calling API() gives us an Axios instance that we can call .get or .post on! So here’s the code that will get our random quote.

import API from './API'

export default {
    getQuote() {
        return API().get('/')
    },
}

Then, inside App.vue, let’s make our component use this new file with its reusable API call instead of creating Axios all on its own. 

const loadQuote = async () => {
      try {
        const response = await KanyeAPI.getQuote() // <--- THIS LINE
        quote.value = response.data.quote
      } catch (err) {
        console.log(err)
      }
}

That’s it! If we load up our app, we’re still loading in quotes perfectly.

Now, let’s move this our createPost into its own reusable method. 

Back in KanyeAPI.js, let’s add createPost to the export default, and this will take the data for the post request as an argument that we can pass to our HTT{ request. 

Similar to our GET request, we want to return our API to get an axios instance, but this time we need to override the default URL value and pass in our JSONplaceholder url. Then, we can call Axios post like we’re used to.

export default {
    getQuote() {
        return API().get('/')
    },
    createPost(data) {
        return API('https://jsonplaceholder.typicode.com/').post('/posts', data)
    }
}

Easy as that.

Back in App.vue, we can call our new post method like this.

const createPost = () => {
      const response = await KanyeAPI.createPost(JSON.stringify({
          title: 'foo',
          body: 'bar',
          userId: 1,
      }))

      console.log(response)
}

Now, when we click our button, we’ll see that our dedicated API files are working – giving us a 201 code meaning we had a successful post. 

And that’s it!

The great thing about moving our API calls out of these Vue components and into their own files is that we can now use these API calls wherever we want across our app. It lets us create more reusable and scalable code. 

I hope this helped and happy coding!

Finished Vue and Axios Code

<template>
  <div>
    <i>"{{ quote }}"</i>
    <p>- Kanye West</p>
    <p>
      <button @click="createPost">Create Post</button>
    </p>
  </div>
</template>

<script>
import axios from 'axios'
import { ref } from 'vue'
import KanyeAPI from './services/KanyeAPI'
export default {
  setup () {

    const quote = ref('')

    const loadQuote = async () => {
      try {
        const response = await KanyeAPI.getQuote()
        quote.value = response.data.quote
      } catch (err) {
        console.log(err)
      }
    }

    loadQuote()
    
    // axios.get('https://api.kanye.rest/')
    //   .then(response => {
    //     // handle response
    //     quote.value = response.data.quote
    //   }).catch(err => {
    //   console.log(err)
    // })

    const createPost = () => {
      const response = await KanyeAPI.createPost(JSON.stringify({
          title: 'foo',
          body: 'bar',
          userId: 1,
      }))

      console.log(response)
      // axios.post('https://jsonplaceholder.typicode.com/posts', JSON.stringify({
      //     title: 'foo',
      //     body: 'bar',
      //     userId: 1,
      // })).then(response => {
      //   console.log(response)
      // })

      
    }
    
    return {
      createPost,
      quote
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
import axios from 'axios'

export default(url='https://api.kanye.rest') => {
    return axios.create({
        baseURL: url,
    })
}
import API from './API'

export default {
    getQuote() {
        return API().get('/')
    },
    createPost(data) {
        return API('https://jsonplaceholder.typicode.com/').post('/posts', data)
    }
}