FCC Camper Leaderboard using VueJS

Pankajashree R
Chingu
Published in
3 min readAug 30, 2017

The second project under Data Visualization Certification from FreeCodeCamp is to build a Camper leaderboard. Fetching 2 types of data from the API and toggling between the two views using one click is the key part of this app.

You can see the final demo of the app here.

By experimenting on the various ways to implement this app, I learnt more about using props to send data between components, life-cycle hooks to load data from the API once the component is created and creating tabs to switch between past 30 days and all time campers.

Since I have already explained about setting up a simple vue app using webpack template in the first project, I will only explain about the different components and the app-logic in this post.

App Components:

This app contains the following components:

  1. Header and Footer — similar to the ones created in the first project
  2. Table -grid— to display the campers info as a table
  3. Alltime and Recent components fetching their respective data and displaying using the table-grid component.
  4. Main App — Switching between two tabs.

Table-grid component

The table-grid component is a simple table which takes 2 props — column headings and column data — both of them arrays:

props: {
colTitles: Array,
colData: Array
}

Using v-for directive, iterate over both the arrays to display the table heading and table rows.

Vue.js allows us to define filters that can be used to apply common text formatting. I have defined a filter to display column headings as capitalized text. The reason for using this filter to capitalize text is that, data representation should be taken care of by the component itself. While sending the column-titles as a prop to the table component, we need not worry about styling it.

I have defined a filter named capitalize:

filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}

Using this filter while displaying column titles —

<th v-for="coltitle in colTitles">
{{coltitle | capitalize}}
</th>

Alltime and Recent components

The only difference between these 2 components lies in the URL from which we fetch the data about campers.

There are 4 columns titles— Serial number, Camper name, Points earned in past 30 days and All time points.

Column data is declared as an empty array which will be populated later using a method.

data () {
return {
colTitles: ['#', 'camper Name', 'points in past 30 days', 'all time points'],
colData: []
}
}

The method fetchColData() uses the Javascript fetch API and returns a JSON object which is stored in colData. This method is called once the component has been initialized and data is active using the created() life-cycle hook.

methods: {
fetchColData: function() {
fetch('https://fcctop100.herokuapp.com/api/fccusers/top/recent')
//or 'https://fcctop100.herokuapp.com/api/fccusers/top/alltime' .then(response => response.json())
.then(json => this.colData = json)
}
},
created() {
this.fetchColData()
}

Finally using the table-grid component, v-bindthe props col-titles and col-data with the component’s data items colTitles and colData.

<table-grid :col-titles = 'colTitles' :col-data = 'colData'>
</table-grid>

We now have two tables —Top Campers for the Past 30 days and All time campers.

Main app component

For switching between Past 30 days and All time campers, I used this component to create 2 tabs. Awesome-vue is a great place to find resources, reusable components and libraries with good documentation.

<vue-tabs>
<v-tab title="Past 30 Days Leaders">
<past></past>
</v-tab>
<v-tab title = "All time Leaders">
<alltime></alltime>
</v-tab>
</vue-tabs>

App Demo

The project is live here.

Source code is here.

The Project finally looks like this —

FCC Camper Leaderboard

--

--