Async in Vuejs -Part 2

Francesco Zuppichini
Published in
4 min readSep 4, 2017

--

Let’s create a random cocktail app

In Part 1 of this tutorial we have seen how to create a skeleton card that can be used as a loading feedback instead of a classic boring spinner.

If you miss it you can check it here:

https://medium.com/@FrancescoZ/async-in-vue-js-part-1-28d96f751a2e

Today we are going to building this:

https://francescosaveriozuppichini.github.io/random-cocktails-app/

A random cocktail single page app. We will discover how to fetch data from an API and use the previously created skeleton card component to improve the user experience.

I will keep things simple by just using a single component with all the logic inside it, so no state management library will be used. Keep in mind that is just an example, you should always keep your state separated from the components.

Let’s get started!

Implementation

Before starting, let me just say that we are only going to focus only on the asynchronous parts and not on the design. As always you can find all the code on GitHub:

https://github.com/FrancescoSaverioZuppichini/random-cocktails-app

Again, we use drawio2vuejs to quickly create the projecj and, again, we are going to use Vuetify as main UI framework.

https://github.com/FrancescoSaverioZuppichini/DrawIo2Vuejs

First, we create the basic project template by calling.

vue init vuetifyjs/webpack random-cocktails-app

We need two components, Cocktails and Cocktail . So just create the draw.io diagram and call the drawio2vuejs cl as we did in the last part.

Cocktails will hold all the logic behind calling the API and display the correct content, in our case, a list of cocktails. So, open Cocktails.vue and add in the data field:

//Cocktails.vue
...
data: function() {
return {
isLoading: false,
cocktails: []
}
},
...

Where isLoading will be used to know when we need to display our loading feedback. We also need a method that will get and add a new random cocktail, for simplicity we called it getMore

//Cocktails.vue
...
methods: {
getMore() {
this.isLoading = true

axios.get(API_URL)
.then(({ data }) => {
var cocktail = data.drinks[0]
this.cocktails.push(cocktail)
cocktail.ingredients = this.createIngrediens
(cocktail)
this.isLoading = false
})
.catch(err => this.isLoading = false)
},
}
...

You can see isLoading is set to true before calling the endpoint and toggled after. Since the returned JSON has not a real array with all the ingredients, I have created a util method called createIngredients to do so.

I added a button below the last Cocktail to trigger the previously created method and fetch a new one every time. Easily the template is composed by a list of Cocktail component and some Vuetify component to create the single page layout:

<template>
<v-container>
<transition-group name="fade" class='layout row wrap align-center' mode="out-in">
<v-flex xs12 :key="cocktail.idDrink" v-for="cocktail in cocktails">
<cocktail :cocktail="cocktail" class='mb-2'>
</cocktail>
</v-flex>
</transition-group>
<v-flex xs12>
<v-layout column align-center>
<v-btn primary @click="getMore()"> Get More</v-btn>
</v-layout>
</v-flex>
</v-container>
</template>

I have also added a Vue.js transition-group element to create a nice fade in animation when a new Cocktail appears. If we try the app now, we can notice that everything works but we are still missing something.

Can you spot it?

Yes! We are missing a loading feedback. Let’s use the skeleton card that we create in the last part of this tutorial series. You can install it by just:

npm install -S skeleton-card-vuejs

Then, import as a normal component:

import SkeletonCard from 'skeleton-card-vuejs'

Now add it the Cocktails.vue template and set the correct props to mimic the content we want to load. In this case, we do not a header and the orientation is horizontal. Also, we want to see it only when isLoading is true.

//Cocktails.vue<template>
<v-container>
<transition-group name="fade" class='layout row wrap align-center' mode="out-in">
<v-flex xs12 :key="cocktail.idDrink" v-for="cocktail in cocktails">
<cocktail :cocktail="cocktail" class='mb-2'>
</cocktail>
</v-flex>
<v-flex xs12 v-show="isLoading" key='loading'>
<skeleton-card class='skeleton-card--opacity' :hasHeader="false" :isHorizontal="true"> </skeleton-card>
</v-flex>
</transition-group>
....
</v-container>
</template>

And then it will appear when a new cocktail has been fetched

better uh?

If you want to discover new cocktails, you can find the app here:

https://francescosaveriozuppichini.github.io/random-cocktails-app/

Conclusion

In this last part of “Async in Vue.js” we have seen how to properly load some content with axios and show a loading feedback using a skeleton card to give to the user fist clue of what is going to be displayed and a better experience.

You may also find these articles interesting:

If you have any feedbacks, please leave a comment.

Thank you for reading

Francesco Saverio Zuppichini

--

--