# Create a Javascript Covid 19 Tracker

In this article, we will be building a web-based COVID 19 tracker using HTML, CSS, and Javascript, which tracks the coronavirus cases in the World for the last three months and shows it in a **line graph**. The project is pretty easy and straightforward. You can create a COVID tracker and show it off to your friends!

Things we'll implement in building this tracker are

- 👨‍🍳 API
- 🤞 Promises
- 🅱 Bootstrap 
- 📉 ChartJS 
- 🧠 Brain! 

**File Structure for the App:**

COVID Tracker App

- `index.html`
- `styles.css`
- `scripts.js`

So, let's start.

## 🦴 Creating the Markup

Our HTML file doesn't contain a lot of code. The only necessary thing we need in the HTML except the boilerplate is the Canvas. The canvas is used by the ChartJS library(which we'll see later) to create a chart.

**HTML Markup:**

```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./styles.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

    <title>Track Covid Tonight</title>
</head>

<body>
    <div class="container">
        <h1 class="text-center mt-4 heading">Track Covid Tonight</h1>
        <canvas id="myChart"></canvas>
    </div>
    <div class="myList"></div>
    <script src="./scripts.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
</body>

</html>
```

As you can see, our HTML file contains the bootstrap CSS file, a local `styles.css` file, and the most important `scripts.js` file. We also need the ChartJS library to display the chart. We have used CDNs(content delivery networks) for bootstrap and the Chart.

The markup has an `h1` element which shows the heading and a canvas that renders the chart. We've enclosed both the h1 and the canvas inside the bootstrap class called the container. Now let's see our `styles.css` file.
## 🎨Adding Styles

**styles.css**

```CSS
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
}
```

If you want to style the app with your own styles, you can do so. I'd love to see your designs. However, I've kept the app minimal. Our `styles.css` file resets the default styles and adds height to the body element. We are using CSS `vh` unit which represents the viewport height. We are setting to `100vh `which means the body will cover the complete viewport.

## 🤴 Adding JavaScript Functions
Now, let's jump to the most important file. The `scripts.js` file. Our `scripts.js` file contains all the necessary codes to fetch and display the data.

**scripts.js**

```javascript
const api = 'https://disease.sh/v3/covid-19/historical/all?lastdays=90';

const getData = async () => {
  const response = await fetch(`${api}`);
  if (response.ok) {
    return await response.json();
  } else {
    return Promise.reject(response.status);
  }
};

const result = getData();
result
  .then((data) => {
    let date = Object.keys(data.cases);
    let total = Object.values(data.cases);
    let deaths = Object.values(data.deaths);
    let recovered = Object.values(data.recovered);

    var ctx = document.getElementById('myChart').getContext('2d');
    let myChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: date,
        datasets: [
          {
            label: 'Total Cases',
            data: total,
            borderColor: 'rgba(255, 99, 132)',
            fill: false,
          },
          {
            label: 'Recovered Cases',
            data: recovered,
            borderColor: 'rgba(153, 102, 255, 1)',
            fill: false,
          },
          {
            label: 'Deaths',
            data: deaths,
            borderColor: 'rgba(75, 192, 192, 1)',
            fill: false,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [
            {
              scaleLabel: {
                display: true,
                labelString: 'Numbers in Thousands',
              },
            },
          ],
          xAxes: [
            {
              scaleLabel: {
                display: true,
                labelString: 'Date(DD/MM/YYYY)',
              },
            },
          ],
        },
        title: {
          display: true,
          text: `Coronovirus Cases in India for Last Three Months`,
        },
      },
    });
  })
  .catch((error) => {
    console.log('Error: ', error);
  });
```

Don't get scared. The file looks scary, but it isn't. We'll understand the file by breaking in into parts.

Let's start at the top. We will use an API called [disease.sh](https://disease.sh/) to fetch our data. I hope you know what an API is? API stands for **Application Programming Interface**. An API works as a waiter between the client and the server to put it in easy words. We ask for data from the server using the API, and the server returns our data through the API. It works as an intermediary.

We'll use the **disease.sh** to fetch coronavirus cases for the last 90 days. To fetch data from a date range, the API uses the below endpoint

```
https://disease.sh/v3/covid-19/historical/all?lastdays=NO-OF-DAYS
```

We are setting the number of days to 90. Then we are fetching the data using an async function. First, let's see how the data looks like,

![JSON Data from disease.sh for covid tracker](https://i.ibb.co/vk7kc7D/1.png)

I've reduced the days to 10 to make it look cleaner here. This data might look cluttered in your browser. I've used a JSON formatter extension to look it cleaner. So, the API returns us three objects, i.e., cases, deaths and recovered. Each of the objects contains a key-value pair of date and numbers. The numbers represent the number of cases, deaths and recoveries. I think you get the idea. Now let's see how we fetch the data using the API.

```javascript
const api = 'https://disease.sh/v3/covid-19/historical/all?lastdays=90';

const getData = async () => {
  const response = await fetch(`${api}`);
  if (response.ok) {
    return await response.json();
  } else {
    return Promise.reject(response.status);
  }
};
```

We've added basic error handling to the function. If the `response.ok` is true, only then our promise will resolve. Otherwise, it'll reject and return an error. Also, we are using JavaScript `template literals` to fetch the API in our `getData` function. After creating the function we will be storing the data returned in a variable called `result`. Because the function will also return a promise, we have to handle it using a `then `statement. If you are not comfortable with JavaScript Promises, you can check the [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) docs.

```javascript
const result = getData();
result
  .then((data) => {
    let date = Object.keys(data.cases);
    let total = Object.values(data.cases);
    let deaths = Object.values(data.deaths);
    let recovered = Object.values(data.recovered);
};
```

This is the first part of our `then `statement. First, we are storing the dates in an array called `date`. We are sorting the data in arrays because ChartJS supports arrays. The `Object.keys` method returns an array containing the key properties from an object. We are targeting the keys because the API returns the values in a `key-value` pair of dates and cases. Then we are targeting the total cases, deaths and recoveries similarly and storing them to corresponding variables. You can `console.log` the values to see how the arrays look.

![Returned Arrays for covid tracker](https://i.ibb.co/Xjf6C9L/2.png)

We are almost done with the data. The only thing which is left now is visualizing the data. To visualize, we'll be using a popular data visualization library called Chart.js. It is a lightweight library which can make it easy to visualize data in popular formats like a bar chart, line chart, pie chart and more. We'll be using the line chart here.

Let's see the `myChart `function.

```javascript
    var ctx = document.getElementById('myChart').getContext('2d');
    let myChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: date,
        datasets: [
          {
            label: 'Total Cases',
            data: total,
            borderColor: 'rgba(255, 99, 132)',
            fill: false,
          },
          {
            label: 'Recovered Cases',
            data: recovered,
            borderColor: 'rgba(153, 102, 255, 1)',
            fill: false,
          },
          {
            label: 'Deaths',
            data: deaths,
            borderColor: 'rgba(75, 192, 192, 1)',
            fill: false,
          },
        ],
      },
      options: {
        scales: {
          yAxes: [
            {
              scaleLabel: {
                display: true,
                labelString: 'Number of Cases',
              },
            },
          ],
          xAxes: [
            {
              scaleLabel: {
                display: true,
                labelString: 'Date(DD/MM/YYYY)',
              },
            },
          ],
        },
        title: {
          display: true,
          text: `Coronavirus Cases in the World for 90 Days`,
        },
      },
    });
```

The first thing we are doing here is, we are targeting our `canvas `which has an ID of `myChart`. The `getContext `gives access to the canvas tags 2D drawing functions. Then using the Chart constructor, we're creating a function that contains all the necessary configurations for the chart. The type:` 'line'` specifies the type of chart. The `data `object holds all the `datasets`, `labels `and other data related configurations. We are passing our date variable as the label for our chart using `labels: date`. The `datasets `are an array of objects which hold the label, data, and colors for each line. There are a lot of other configurations available. But to keep this article simple we are using minimal options. You can check their documentation to get an idea about available options [here](https://www.chartjs.org/docs/latest/). After the `data `object, we are setting up a few options for the look. The labels for x and y axes are set using the `yAxes` and `xAxes `objects. And the title for the chart is setup using the `title `object. We have completed our code. The last thing left is to catch any error. The `catch `statement is used in promises to catch errors. For this app, we'll catch the error and `console.log` it into the console.

```javascript
.catch((error) => {
    console.log('Error: ', error);
});
```

After following all the steps, our app will look like this,

![create javascript Covid Tracker](https://i.ibb.co/7JpDqmL/3.png)

You can check the live version of the app [here](https://track-covid-tonight.vercel.app/). And to see the source code, visit [`here`](https://github.com/nemo0/track-covid-tonight).

I hope you enjoyed building this tracker. I've tried to keep it simple. Now try building your own COVID tracker and share it with us. 


