Probably the hottest thing around right now has to do with the blockchain and the various cryptocurrencies like Bitcoin and Litecoin. There are quite a few services out there that will let you track the market and your portfolio, but what if you wanted to build a customized tracker to meet your needs?
If you've been keeping up with my content, you'll remember that I had published something similar for CODE Magazine titled, An Introduction to Native Android and iOS Development with NativeScript, which included a demo for building a NativeScript with Angular cryptocurrency tracker. However, what if you didn't want to use Angular or even a mobile framework?
We're going to see how to create a cryptocurrency market tracker for the web using the very popular Vue.js JavaScript framework and a remote web service.
Creating a Vue.js Web Application with the Vue CLI
To make our lives easier, we're going to scaffold our project using the Vue CLI. If you don't already have it, I highly recommend obtaining it for Vue.js projects.
From the command line, execute the following to create a new project:
vue init webpack crypto-project
Answer all the questions to the best of your ability. When asked about scaffolding a project with the compiler and runtime built in, it doesn't really matter what you choose for this example. When asked about a router, decline because our application will consist of a single component.
Including the Bootstrap CSS Framework and the Project Dependencies
There are a few dependencies that we'll need to obtain to make this project possible. Rather than trying to use CSS skills that we may or may not have, we're going to use Bootstrap as our CSS framework.
To include Bootstrap in our project, open the project's index.html file and make it look like the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>crypto-project</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</body>
</html>
We've essentially added what was requested in the Bootstrap getting started documentation.
Since we're going to be making requests against a remote web service, we're going to need a third-party package that will make HTTP requests easier.
Within the project, and from the CLI, execute the following:
npm install axios --save
For this example, we're going to be using the axios package for making HTTP requests. There are plenty of alternatives, but it is more or less your preference. For more information on using axios or some alternatives, check out a previous article I wrote titled, Consume Remote API Data via HTTP in a Vue.js Web Application.
Developing the Application Logic and HTML User Interface
For this project, HTTP requests are going to be the backbone of the application. The rest will consist of a nice Bootstrap UI and a lot of data binding.
Notice we have a list of several coin values and a form for doing our own dollar-to-cryptocurrency conversion.
So how do we make this possible?
Let's start by opening our project's src/App.vue file and preparing it for development:
<template>
<div class="container-fluid">
</div>
</template>
<script> import axios from "axios"; export default { name: 'app', data() { return { coins: [], input: { amount: 1, cryptocurrency: "bitcoin" }, specific_coin_amount: 0 } }, mounted() {}, methods: {} } </script>
<style> body { margin-top: 50px; background-color: #F0F0F0; } .example { border: 1px solid #DDDDDD; border-radius: 4px; padding: 10px; background-color: #FFFFFF; } </style>
In the above code, we're doing a few things to set us up for what comes next. First, we're importing the axios package that we had previously downloaded. Next, we're defining the variables that will be used throughout the application. We have to initialize them to prevent errors later.
The coins
variable will hold a list of cryptocurrencies and information about them. Anything found in the input
variable will be bound to a form element. The specific_coin_amount
will be a converted value based on user input.
The mounted
method will allow us to do things when the application loads and then we'll have custom methods for doing conversions on request.
Let's dig deeper into the mounted
method:
mounted() {
axios({ method: "GET", "url": "https://api.coinmarketcap.com/v1/ticker/?limit=20" }).then(result => {
this.coins = result.data;
}, error => {
console.error(error);
});
},
In the above code, we are issuing a GET request to a popular market tracker called CoinMarketCap. Based on the API documentation, we know we are getting an array of cryptocurrencies as a response. In particular we are receiving 20 based on our limit that we set.
Now let's look at creating a custom method:
methods: {
convert() {
axios({ method: "GET", "url": "https://api.coinmarketcap.com/v1/ticker/" + this.input.cryptocurrency + "/" }).then(result => {
this.specific_coin_amount = this.input.amount / result.data[0].price_usd;
}, error => {
console.error(error);
});
}
}
Again, we're issuing an HTTP request to the CoinMarketCap API, but this time for a particular ticker based on whatever the user had eventually selected. Within the response, we are taking the user-defined amount and dividing it by the coin value in the response to give us a proper conversion.
Alright, so what does the UI look like for us? Let's take a look at the <template>
block in our src/App.vue file:
<template>
<div class="container-fluid">
<div class="row">
<div class="col-md-8">
<div class="example">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Symbol</th>
<th>Price (USD)</th>
<th>7 Day Change (%)</th>
</tr>
</thead>
<tbody>
<tr v-for="coin in coins">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<div class="example">
<form>
<div class="form-group">
<label for="usd">Amount (USD)</label>
<input type="text" class="form-control" v-model="input.amount" id="usd" placeholder="Amount (USD)">
</div>
<div class="form-group">
<select v-model="input.cryptocurrency">
<option v-for="coin in coins" v-bind:value="coin.id"></option>
</select>
</div>
<button type="button" class="btn btn-default" v-on:click="convert()">Convert</button>
</form>
<br />
<p>
<strong>Value:</strong>
</p>
</div>
</div>
</div>
</div>
</template>
A bulk of the above HTML is purely Bootstrap markup.
There are two parts to the UI. We are listing the coins returned from the mounted
method, and we are allowing user-defined conversions through the convert
method.
<tbody>
<tr v-for="coin in coins">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
In the table, we loop through the coins
variable found in the <script>
block. Each item in the array is listed in the table.
<form>
<div class="form-group">
<label for="usd">Amount (USD)</label>
<input type="text" class="form-control" v-model="input.amount" id="usd" placeholder="Amount (USD)">
</div>
<div class="form-group">
<select v-model="input.cryptocurrency">
<option v-for="coin in coins" v-bind:value="coin.id"></option>
</select>
</div>
<button type="button" class="btn btn-default" v-on:click="convert()">Convert</button>
</form>
<br />
<p>
<strong>Value:</strong>
</p>
The form has an <input>
element and a <select>
element, both bound to parts of our input
variable defined in the <script>
block. When the <button>
is clicked, the convert
method is triggered, updating the specific_coin_amount
value that is rendered to the screen.
Conclusion
You just saw how to create your own cryptocurrency coin tracker using the Vue.js JavaScript framework and a publicly accessible cryptocurrency market tracker API. There are many ways to issue HTTP requests in Vue.js, as outlined in my previous article, but regardless of the approach, it is all very simple to do.
If you're interested in accomplishing something similar with the Angular framework and NativeScript, check out my article on CODE Magazine.