DEV Community

Cover image for Working with REST APIs in Vanilla JavaScript: Build a currency converter
Emmanuel Ugwu
Emmanuel Ugwu

Posted on • Updated on

Working with REST APIs in Vanilla JavaScript: Build a currency converter

JavaScript has grown very popular due to its ability to be used in multiple use cases and friendly learning curve. This is because developers are prone to go for a language that can be used to build basic as well as advanced applications. We’ll show this by building a multi-currency converter app using plain JavaScript. The main prerequisite for understanding this article is knowledge of vanilla JavaScript.

Getting Started

Every client side JavaScript application can be broadly divided into three parts —HTML, CSS and JavaScript. Let’s create our HTML file:

    // fx.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
    </head>
    <body>
    </body>
    </html>
Enter fullscreen mode Exit fullscreen mode

In the code sample above, we created a barebone HTML file which will contain all our HTML components. Let's do the same for our CSS file:

    //fx.css
    body{
        padding: 0;
        margin: 0;
        box-sizing: border-box;
    }
Enter fullscreen mode Exit fullscreen mode

Defining our components

Sign In Feature

First things first, let's look into building a sign-in feature that gives end-user accessibility to the currency exchange feature which we’ll implement a function to accept a username and password credential through our input elements. Using a localStorage read-only property, the key/value (credentials) pairs are stored across browser sessions. Key/Value provided by the end-user are always in a UTF-16 DOMString format, which uses two bytes per character and is automatically converted to strings. The stored data in our localStorage object will not be deleted when the browser is closed and it has no expiration date - be it the next day, a week, or a year. The purpose of storing a user’s key/values is to access and display his/her username when logged in. To store an end-user’s data, we need to create a syntax for saving data to localStorage:

    localStorage.setItem("key", "value");
Enter fullscreen mode Exit fullscreen mode

To read the data, we’ll need to apply another syntax:

    var lastname = localStorage.getItem("key");
Enter fullscreen mode Exit fullscreen mode

Accepting our end-user key/values

After storing our data using a localStorage property, we apply an IF/ELSE statement to verify if the credentials meet certain conditions. The following conditions include:

  • The username or password cannot be left blank.
  • The username or password must contain at least 8 characters.

Using the code snippet below we were able to achieve such conditions.

    //create a condition the username and password must fulfil
        if(userName === ''){
          alert('Username cannot be left blank');
        } else if(userName.length <= 7){
          alert('Username must contain at least 8 characters');
        } else if(userName.length >= 7){
          console.log(true)
        }
        if(passWord === ''){
          alert('Password cannot be left blank');
        } else if(passWord.length <= 7){
          alert('Password must contain at least 8 characters');
        } else if(passWord.length >= 7){
          console.log(true)
        } 
    // if the username and password meet the conditions
        if(userName.length >= 7 && passWord.length >= 7){
          return true;
        } else{
          return false;
        } 
Enter fullscreen mode Exit fullscreen mode

If the values inputted by the user meet the condition standards, the next step will be to hide the visibility of our sign-in page and introduce the currency converter feature. The function hide() embedded into our dispData() function makes that transition possible.

    function hideData(){
    if (y.style.display == 'none') {
        y.style.display = 'block';
        x.style.display = 'none';
        signOut.style.display = 'block';
      } y.style.display = 'block';
        x.style.display = 'none'; 
        signOut.style.display = 'block';
    }
Enter fullscreen mode Exit fullscreen mode

A sign-out button is also created, attached to it is an event listener to reload the the page back to normal once its clicked. The sign-out button serves the purpose of ending a user’s session. The code below is a snippet of the event listener:

    //to sign out of the app
    signOut.addEventListener('click', () => {
      window.location.reload();
    })
Enter fullscreen mode Exit fullscreen mode

Introducing our currency converter

Implementing our elements

With the implementation of these elements:

  • an input element to modify a currency’s amount,
  • two select elements (both currencies) for easy navigation through multiple currencies and
  • a button element,

the main body of the application is set. The SVGs utilized in building this application are gotten from Undraw which provides open-source illustrations and has a lot of options to choose from.
In the HTML code shown below, the select elements have options containing the full name of a currency (data-name) as its value :

    <option value="AED" data-name="United Arab Emirates dirham">AED</option>
Enter fullscreen mode Exit fullscreen mode

Using JavaScript, we can simply assign the corresponding full currency name to a variable so that when an option is selected, the name of the currency is changed to the selected currency with the help of an eventListener.

Formatting our currency

The Intl.NumberFormat provides us with the relevant currency symbol of a selected currency. Using a constructor, it creates a new NumberFormat object which returns a string outputting the desired currency format.
Options in an array of objects form can be placed as such:

    const formatOptions = {
        style: "currency",
        currency: currencyCode,
        minimumFractionDigits: 2,
        currencyDisplay: "symbol",
      };
Enter fullscreen mode Exit fullscreen mode

which formats the returned string into a currency format, including its currency symbol.

Now, we need to use the above options to create the NumberFormat, employing it to a variable to update the HTML.

    const currencyFormatText = new Intl.NumberFormat("en-US", formatOptions).format(number);
Enter fullscreen mode Exit fullscreen mode

While making use of the NumberFormat, we’ll employ an event listener to switch the name of a currency once it changes. The code snippet below is the function which runs when our event listener calls on it:

    function updateCurrencyName(e) {
    // grab data attribute
      const currencyNameOne = inputOriginalCurrency.selectedOptions[0].dataset.name;
      const currencyNameTwo = inputNewCurrency.selectedOptions[0].dataset.name;
      // grab the elements
      fromCurrencyText = document.querySelector("#fromCurrencyText")
      toCurrencyText = document.querySelector("#toCurrencyText");
      // update html with currency details
      fromCurrencyText.innerHTML = currencyNameOne;
      toCurrencyText.innerHTML = currencyNameTwo;
    }
Enter fullscreen mode Exit fullscreen mode

For better functionality, let’s create another function to accept only a given set of characters. A keydown event listener can stop the value being from being inputted if it doesn't match the list of allowed characters. The code block below shows the created function.

     function checkNumberKey(e){
    // stop default adding typed value to input
      e.preventDefault();
      // set allowed values
      const allowedKeys = "0123456789";
      const keyArray = allowedKeys.split("");
      const allowOnce = ".";
      // adds to input if matches allowed characters
      if(keyArray.includes(e.key)){
        inputAmount.value += e.key;
      }else if(!inputAmount.value.includes(".") && e.key === allowOnce){ // allows . if not present
        inputAmount.value += e.key;
      }
    }
Enter fullscreen mode Exit fullscreen mode

Finding an API

What is an API?

The heart of this application is its API (Application Programming Interface) — “an interface between multiple software applications or mixed hardware-software intermediaries”. In simpler terms, the idea of an API is to have your app server talk directly to the API’s server with a request to access its data. Your app server will then receive the API’s response, which will return the data, then you can utilize the data whichever way you want. Exchangerates API is a suitable option as it provides endpoints to access most recent exchange rates for currencies.

API key

To make secure HTTP requests to Exchangerates API, you will need to create an account to be issued a private access key. The private access key is a unique identifier that gets passed into the API as an URL parameter access_key. This parameter serves as a unique identifying authentication with the Exchangerates API. The image below shows Exchangerates API subscription plans:

Alt Text

NOTE: Please do not share your private keys with any individual, or public websites.

Integrate into your application

The private access key is integrated into the base URL to access its data.

Base URL:

    http://api.exchangeratesapi.io/v1/”
Enter fullscreen mode Exit fullscreen mode

The API comes with a number of endpoints where each of them provides different functionalities. We’ll authenticate the Exchangerates API with the access_key parameter while using an endpoint for the latest rates.
This endpoint returns exchange rate data in real-time for all available currencies or for a specific set.

Append your API Key:

    // personal key
      const apiKey = "not-the-actual-key";
      // add the key to the base url
      const url =
      "http://api.exchangeratesapi.io/v1/latest?access_key=" + apiKey;
Enter fullscreen mode Exit fullscreen mode

Making an API request

To properly access and utilize our API’s data, an async function with an await fetch method is used to start an HTTP request to the API’s server, then the server sends back a response, which is in form of data  - likely in a format like JSON. Because the await keyword is present, the asynchronous function is paused until the request completes.

    // send a HTTP request to the API
      const response = await fetch(url);
      const data = await response.json();
Enter fullscreen mode Exit fullscreen mode

API Response

The API response in a standard JSON format contains information about numerous currencies commonly used, all in connection with the Euro currency and time-stamped with time information of the collected information.

Example Response:

    {
        "success": true,
        "timestamp": 1519296206,
        "base": "EUR",
        "date": "2021-03-17",
        "rates": {
            "AUD": 1.566015,
            "CAD": 1.560132,
            "CHF": 1.154727,
            "CNY": 7.827874,
            "GBP": 0.882047,
            "JPY": 132.360679,
            "USD": 1.23396,
        [...]
        }
    }
Enter fullscreen mode Exit fullscreen mode

Handling the API’s data

As we can see from the example above, when we make a request using the API's latest rates endpoint, it returns exchange rates in real-time. The API response always contains a rates object that contains the exchange rate data.

Let’s assign the data.rates to a const, so we can easily obtain the data of any currency selected in our currency input using the base object which contains the short currency code of the currency. From the code snippet below, divide the inputNewCurrency exchange rate against that of inputOriginalCurrency, then we multiply with our amount. After that, the result is displayed in the HTML.

    {
    // access the currency rates embedded in JSON
      const rates = data.rates;
    // convert from currency a to b
      const FXRate = rates[inputNewCurrency.value]/rates[inputOriginalCurrency.value];
      // actually calculate the new amount
      const toAmount = amount * FXRate;
      // update html with xchange details
      const msg = `${fromText} = ${toText}`;
      outputAmount.innerHTML = msg;
    }
Enter fullscreen mode Exit fullscreen mode

Video

Watch a video of our application in use

Conclusion

Building applications can seem daunting at times. Fortunately, JavaScript provides an all purpose platform for developers to work with. To have an overview of the code base for this article, you can check it out on GitHub.

Top comments (0)