What is an API & how to fetch it in React with Hooks? ⚓
Tags: tutorial, react, webdev, javascript
Published: 2020-05-28 13:56:00

Whether you are new to APIs or want to use your favourite Hook, this is a tutorial for you. Before going any further into React and stuff, let me introduce you with APIs and how they work so you have a better understanding of what we're about to do.

For this, I assume you already know about React and Hooks. If not the [official docs](https://reactjs.org/docs/hooks-intro.html) should be enough to get a taste of what they do. Basically, if you want to use React app state without the writing a [`Class`](https://reactjs.org/docs/hooks-state.html#equivalent-class-example), then Hooks are a great way to jump right in.

The following article might help you in the way:

{% link https://dev.to/vaibhavkhulbe/hello-test-55l1 %}

## What's an API and what it does? 🧐

Technically, API stands for Application Programming Interface. But what do those words mean? Okay, here me out...

> It's like a shared boundary across which your application and the data from a server (or a database probably) interact and exchange information need to do some action or run the app.

The most common thing you do is make calls (yes, you literally _call_ a method/function of that API) to and from the app. One important thing to note is that an API is not a remote server, rather it's a part of it. The server has the job to receive and send response packets.

There are varied examples on the internet where you interact with APIs and might know at all. We all use Facebook, so whenever you're posting a story, writing comments or reacting to a meme, you're interacting with its server wherein the API works as a middleman between you (client) and the Facebook (server).

Here's a diagram from [Perry Eising](https://medium.com/@perrysetgo)'s article on Medium on how an API comes into the picture:

![API diagram](https://dev-to-uploads.s3.amazonaws.com/i/z0dpvnptndfw58k6s1vc.png)
<figcaption>The role of API in an application</figcaption>

You can read the entire article which goes deep into this:

{% medium https://medium.com/@perrysetgo/what-exactly-is-an-api-69f36968a41f %}

Not all APIs work this way. There are some companies/tools which provide you to access their API calls in order to get that particular data to use it in your projects. These can range from fake user generators like [JSONPlaceholder](https://jsonplaceholder.typicode.com/) to a [SuperHero API](https://superheroapi.com/). In the end, their main goal is to give you some data to work on.

![Get it](https://media.giphy.com/media/Ymywwi0yXZxqsfRFMz/giphy.gif)
<figcaption>Who's ready?</figcaption>

---

## Understanding the API 🔄

In this tutorial though, we will be working with a currency API called [Foreign exchange rates API](https://exchangeratesapi.io/) developed by [Madis Väin](https://github.com/madisvain). This is a free service which gets the data from the [European Central Bank](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html).

Here's how we use the exchange rates API:

#### Get the latest currency rates
To get the response, we simply send a GET request:

```
GET https://api.exchangeratesapi.io/latest HTTP/1.1
```
But this will give us the rates in Euros (the default base currency).

#### Get the rates in your own currency
To do this, we simply append `?base` parameter. So, if we want to get the value in USD then the above request becomes:

```
GET https://api.exchangeratesapi.io/latest?base=USD HTTP/1.1
```
Okay, now we know how it works, let's start a React project!

## Using the API in our React app with Hooks 🐱‍💻

#### Step 1: Empty out the default code and inside _App.js_ add the base URL for the API as a `const`.

```js
const BASE_URL = 'https://api.exchangeratesapi.io/latest';
```
Pretty basic step right, well the next one boasts some great stuff. 🔥

#### Step 2: Fetch the API every time the app is loaded.

We use the [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) hook to achieve this. As stated this [Effect](https://reactjs.org/docs/hooks-overview.html#effect-hook) _runs after every completed render_, hence it's seemingly a good choice here.   

**1️⃣** Use JavaScript's native [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to get call the currency rates API, convert the response to JSON and then in the next Promise, we get back the `data`.

```js
// This will only run the first time our app loads
useEffect(() => {
    fetch(BASE_URL)
      .then((res) => res.json())
      .then((data) => {
        // Code for the next step here
     }
  }, []);
```

**2️⃣** Set application state for our currency options list with the [`useState`](https://reactjs.org/docs/hooks-reference.html#usestate) Hook. Be default we don't have any `initialState` therefore we put empty braces in the `useState()`.

```js
const [currencyOptions, setcurrencyOptions] = useState([]);
```
Next, we write the `setcurrencyOptions` function inside the `.then()`. 

```js
setcurrencyOptions([data.base, ...Object.keys(data.rates)]);
```
We pass an array. The first value is the `data` we get back from the API, the second one will be the `keys` from the [JSON `Object`](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) we get in return. By this, our currency options will be set to this value.

At this step, you can `console.log(currencyOptions)`. What you'll get is the first time it just prints out an empty array but in the second run, it gives all the currency options available from the default `EUR` to `MYR`. We now have imported all the base currencies in our app, let's head on to adding some more Hooks.

**3️⃣** Next, we want to have a default currency value to show. For this, we again take advantage of the `useState()` Hook. One will be of the base currency type and the other from which we need to convert to. 

```js
const [fromCurrency, setFromCurrency] = useState();
const [toCurrency, setToCurrency] = useState();
...
const firstCurrency = Object.keys(data.rates)[0];
setcurrencyOptions([data.base, ...Object.keys(data.rates)]);
setFromCurrency(data.base);
setToCurrency(firstCurrency);
```

The `setFromCurrency()` simply gets that base currency and the `setToCurrency()` gets the first option of the `Object.keys()` array. You can go ahead and implement it in your UI code to select/change a particular currency type. Let's now set different amounts.

**4️⃣** That same Hook will be responsible to set the amount as:

```js
const [amount, setAmount] = useState(1);
```
We will let the default value of `amount` to be `1`. We take this a step further by allowing the user to convert both ways simultaneously. So, if they can add the value in the "From" field and get the conversion result in "To" field or vice-versa. The change in one field will directly reflect the other one. For this to work, we need a separate variable to denote this swapping of value fields. 

```js
const [exchangeRate, setExchangeRate] = useState();
const [amountInFromCurrency, setAmountInFromCurrency] = useState(true);
...
setExchangeRate(data.rates[firstCurrency]);
``` 
We added the boolean `true` so that it checks if the amount is changed "from" currency or the "to" currency? As for the actual exchange rate value, we have another `useState()` with no value by default.
Inside the `.then()`, we set the rate value to the rate we get back from the `data` object, passing the `firstCurrency` value. It gives us the actual rate of the currency we select.

**5️⃣** At last, we go further in (without any Hooks now 😌), and add a simple logic building to get all the values we need in order to do the conversion.

```js
let toAmount, fromAmount;
  if (amountInFromCurrency) {
    // The 'amount' in state is 'fromAmount'
    fromAmount = amount;
    toAmount = amount * exchangeRate;
  } else {
    // 'amount' is in 'toCurrency'
    toAmount = amount;
    fromAmount = amount / exchangeRate;
  }
```
So, here it goes. If `amountInFromCurrency` is `true`, then it means that the `amount` value in the state will be in the "from" field. The next link simply multiplies the `amount` with the `exchangeRate` value we go from the above step.

If the `amount` is not in "from", then we do the opposite of multiplication and i.e. (🥁 fake drumroll 🥁) division! Hehe.  

#### Step 3: Update the conversion when we change the currency type.

This bug can simply be removed by using yet another `useEffect()` Hook:

```js
useEffect(() => {
    if (fromCurrency != null && toCurrency != null) {
      fetch(`${BASE_URL}?base=${fromCurrency}&symbols=${toCurrency}`)
        .then((res) => res.json())
        .then((data) => setExchangeRate(data.rates[toCurrency]));
    }
  }, [fromCurrency, toCurrency]);
```
We passed both `fromCurrency` and `toCurrency` because we need to update whenever any one of those value changes. It's a two-way data binding we're doing!

One new thing you see in the code above is we append `&symbols` to the `BASE_URL`. According to the API doc we "Request specific exchange rates by setting the _symbols_ parameter."

```
GET https://api.exchangeratesapi.io/latest?symbols=USD,GBP HTTP/1.1
```
Hence we set the `base` conversion to `fromCurrency` while `symbols` takes in all the values we want it to convert. We do this by dynamically setting `toCurrency`. 

If all went well without any crashes or errors, you can simply implement this in your React component code. 

---

## Where to next? 🤔

You can move ahead and use [APIList.fun](https://apilist.fun/) to try other APIs, use Hooks and add it to your React projects. Not all APIs are free always, make sure you choose the correct one and according to the project size.

---

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">Oh no... Better hit up <a href="https://twitter.com/docsmsft?ref_src=twsrc%5Etfw">@docsmsft</a> for help: <a href="https://t.co/RKvIJcMltv">https://t.co/RKvIJcMltv</a><br><br>Image source: <a href="https://t.co/2UdZDZhoLu">https://t.co/2UdZDZhoLu</a><a href="https://twitter.com/hashtag/DevHumour?src=hash&amp;ref_src=twsrc%5Etfw">#DevHumour</a> <a href="https://twitter.com/hashtag/Developer?src=hash&amp;ref_src=twsrc%5Etfw">#Developer</a> <a href="https://twitter.com/hashtag/Programming?src=hash&amp;ref_src=twsrc%5Etfw">#Programming</a> <a href="https://twitter.com/hashtag/ICYMI?src=hash&amp;ref_src=twsrc%5Etfw">#ICYMI</a> <a href="https://t.co/2GpDO8zAmv">pic.twitter.com/2GpDO8zAmv</a></p>&mdash; Microsoft Developer UK (@msdevUK) <a href="https://twitter.com/msdevUK/status/1253995169088749568?ref_src=twsrc%5Etfw">April 25, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

#### [📫 Subscribe to my weekly developer newsletter 📫](https://mailchi.mp/f59beeac6b9b/devupdates)

##### PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, [here](https://medium.com/@vaibhavkhulbe)'s my Medium profile.