Introduction

In this pandemic period, many of us are suffering due to Corona virus. I have decided to create a simple app to track the important details of Covid-19 and show this data in the dashboard. This app will provide an option to choose a country and display the data of that particular country easily. We will also display the highest recovered top 10 country details along with highest confirmed and highest death details.

API used for getting Covid-19 data

Create Simple COVID-19 Tracker With Angular 10 And Material Design
We are using https://covid19api.com/ to fetch the latest data for Covid-19 affected people. There are various API methods available in this application but for our purpose, we are using only one API method, https://api.covid19api.com/summary This method will provide all the global summary data along with summary of each active countries. These data are currently sufficient for our application. I am not claiming any data accuracy. This is only for learning purpose.

Create Angular 10 application using latest Angular CLI

We can use below CLI command to create new Angular 10 app.
ng new covid19-tracker
After loading all the node packages and dependencies, we can add Angular Material to the project.
ng add @angular/material
We can choose the default theme for material design and choose other default options.
Open the source code in Visual Studio Code.
We must import references for HttpClientModule, MatCardModule, and MatSelectModule modules in app.module.
app.module.ts
  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule } from '@angular/core';
  3. import { AppComponent } from './app.component';
  4. import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
  5. import { HttpClientModule } from '@angular/common/http';
  6. import { MatCardModule } from '@angular/material/card';
  7. import { MatSelectModule } from '@angular/material/select';
  8. @NgModule({
  9. declarations: [
  10. AppComponent
  11. ],
  12. imports: [
  13. BrowserModule,
  14. BrowserAnimationsModule,
  15. HttpClientModule,
  16. MatCardModule,
  17. MatSelectModule
  18. ],
  19. providers: [],
  20. bootstrap: [AppComponent]
  21. })
  22. export class AppModule { }
Create a data service to fetch data from Covid-19 API application.
data.service.ts
  1. import { Injectable } from '@angular/core';
  2. import { HttpClient } from '@angular/common/http';
  3. import { Observable } from 'rxjs';
  4. @Injectable({
  5. providedIn: 'root'
  6. })
  7. export class DataService {
  8. constructor(private http: HttpClient) { }
  9. private url: string = "https://api.covid19api.com/summary";
  10. getData(): Observable<any> {
  11. return this.http.get(this.url)
  12. .pipe((response) => response);
  13. }
  14. }
In above service, we are fetching the summary method from Covid-19 API application.
Create Simple COVID-19 Tracker With Angular 10 And Material Design
Above is the sample response from that API method. This response has two parts. Global summary part and country wise summary part. This is the entire country data as an array.
We can create some model classes inside the model.ts file.
model.ts
  1. export class SummaryData {
  2. Global: GlobalData;
  3. Countries: Array<CountryData>;
  4. Date: Date;
  5. }
  6. export class GlobalData {
  7. NewConfirmed: number;
  8. NewDeaths: number;
  9. NewRecovered: number;
  10. TotalConfirmed: number;
  11. TotalDeaths: number;
  12. TotalRecovered: number
  13. }
  14. export class CountryData extends GlobalData {
  15. Country: string;
  16. CountryCode: string;
  17. Date: Date;
  18. Slug: string
  19. }
We have created three model classes SummaryData, GlobalData, and CountryData.
We can modify the app.component.ts file with below code.
app.component.ts
  1. import { Component, OnInit } from '@angular/core';
  2. import { SummaryData, CountryData } from './models';
  3. import { DataService } from './data.service';
  4. import { DatePipe } from '@angular/common';
  5. @Component({
  6. selector: 'app-root',
  7. templateUrl: './app.component.html',
  8. styleUrls: ['./app.component.css'],
  9. providers: [DatePipe]
  10. })
  11. export class AppComponent implements OnInit {
  12. title = 'covid19-tracker';
  13. summaryData: SummaryData;
  14. indiaData: CountryData;
  15. selectedCountryData: CountryData;
  16. highlyConfirmedData: Array<CountryData>;
  17. highlyDeathData: Array<CountryData>;
  18. highlyRecoveredData: Array<CountryData>;
  19. currentDate: string;
  20. constructor(private service: DataService, private datePipe: DatePipe) { }
  21. ngOnInit() {
  22. let date = new Date();
  23. this.currentDate = this.datePipe.transform(date,'dd-MMM-yyyy');
  24. this.getAllData();
  25. }
  26. getAllData() {
  27. this.service.getData().subscribe(
  28. response => {
  29. this.summaryData = response;
  30. this.getIndiaData();
  31. this.getSortedData();
  32. }
  33. )
  34. }
  35. getIndiaData() {
  36. this.indiaData = this.summaryData.Countries.find(x => x.Slug == "india");
  37. }
  38. getSortedData() {
  39. let data = JSON.parse(JSON.stringify(this.summaryData.Countries));
  40. this.highlyConfirmedData = data.sort((a, b) => b.TotalConfirmed - a.TotalConfirmed).slice(0, 10);
  41. this.highlyDeathData = data.sort((a, b) => b.TotalDeaths - a.TotalDeaths).slice(0, 10);
  42. this.highlyRecoveredData = data.sort((a, b) => b.TotalRecovered - a.TotalRecovered).slice(0, 10);
  43. }
  44. }
We have fetched the global summary data from data service and populated other data for our application. I have used very simple logic for this.
We can modify the app.component.html file with below code snippets.
app.component.html
  1. <div style="width: 1200px;">
  2. <div class="same-row" style="width: 550px;">
  3. <img src="../assets/CovidTracker.PNG">
  4. </div>
  5. <div class="same-row" style="font-weight: bold;">
  6. As on : {{currentDate}}
  7. </div>
  8. <div class="same-row">
  9. <mat-form-field appearance="fill" style="width: 300px;">
  10. <mat-label>Choose a Country</mat-label>
  11. <mat-select [(value)]="selectedCountryData">
  12. <mat-option *ngFor="let country of summaryData?.Countries" [value]="country">{{country.Country}}
  13. </mat-option>
  14. </mat-select>
  15. </mat-form-field>
  16. </div>
  17. </div>
  18. <div>
  19. <div class="same-row">
  20. <mat-card class="covid-card">
  21. <mat-card-header>
  22. <div mat-card-avatar>
  23. <img
  24. src="https://www.sanlam.co.uk/web/media/media/vectors%2018/globe_light_blue_rgb.png?width=32&height=32&mode=crop">
  25. </div>
  26. <mat-card-title>Global Summary</mat-card-title>
  27. <mat-card-subtitle>Total Countries</mat-card-subtitle>
  28. </mat-card-header>
  29. <mat-card-content>
  30. <table>
  31. <tr>
  32. <td>
  33. New Recovered
  34. </td>
  35. <td>
  36. {{summaryData?.Global?.NewRecovered | number}}
  37. </td>
  38. </tr>
  39. <tr>
  40. <td>
  41. Total Recovered
  42. </td>
  43. <td>
  44. {{summaryData?.Global?.TotalRecovered | number}}
  45. </td>
  46. </tr>
  47. <tr>
  48. <td>
  49. New Confirmed
  50. </td>
  51. <td>
  52. {{summaryData?.Global?.NewConfirmed | number}}
  53. </td>
  54. </tr>
  55. <tr>
  56. <td>
  57. Total Confirmed
  58. </td>
  59. <td>
  60. {{summaryData?.Global?.TotalConfirmed | number}}
  61. </td>
  62. </tr>
  63. <tr>
  64. <td>
  65. New Deaths
  66. </td>
  67. <td>
  68. {{summaryData?.Global?.NewDeaths | number}}
  69. </td>
  70. </tr>
  71. <tr>
  72. <td>
  73. Total Deaths
  74. </td>
  75. <td>
  76. {{summaryData?.Global?.TotalDeaths | number}}
  77. </td>
  78. </tr>
  79. </table>
  80. </mat-card-content>
  81. </mat-card>
  82. </div>
  83. <div class="same-row">
  84. <mat-card class="covid-card">
  85. <mat-card-header>
  86. <div mat-card-avatar>
  87. <img src="https://www.countryflags.io/IN/shiny/32.png">
  88. </div>
  89. <mat-card-title>Country Summary</mat-card-title>
  90. <mat-card-subtitle>India</mat-card-subtitle>
  91. </mat-card-header>
  92. <mat-card-content>
  93. <table>
  94. <tr>
  95. <td>
  96. New Recovered
  97. </td>
  98. <td>
  99. {{indiaData?.NewRecovered | number}}
  100. </td>
  101. </tr>
  102. <tr>
  103. <td>
  104. Total Recovered
  105. </td>
  106. <td>
  107. {{indiaData?.TotalRecovered | number}}
  108. </td>
  109. </tr>
  110. <tr>
  111. <td>
  112. New Confirmed
  113. </td>
  114. <td>
  115. {{indiaData?.NewConfirmed | number}}
  116. </td>
  117. </tr>
  118. <tr>
  119. <td>
  120. Total Confirmed
  121. </td>
  122. <td>
  123. {{indiaData?.TotalConfirmed | number}}
  124. </td>
  125. </tr>
  126. <tr>
  127. <td>
  128. New Deaths
  129. </td>
  130. <td>
  131. {{indiaData?.NewDeaths | number}}
  132. </td>
  133. </tr>
  134. <tr>
  135. <td>
  136. Total Deaths
  137. </td>
  138. <td>
  139. {{indiaData?.TotalDeaths | number}}
  140. </td>
  141. </tr>
  142. </table>
  143. </mat-card-content>
  144. </mat-card>
  145. </div>
  146. <div class="same-row" *ngIf="selectedCountryData!=undefined">
  147. <mat-card class="covid-card">
  148. <mat-card-header>
  149. <div mat-card-avatar>
  150. <img src="https://www.countryflags.io/{{selectedCountryData.CountryCode}}/shiny/32.png">
  151. </div>
  152. <mat-card-title>Country Summary</mat-card-title>
  153. <mat-card-subtitle>{{selectedCountryData.Country}}</mat-card-subtitle>
  154. </mat-card-header>
  155. <mat-card-content>
  156. <table>
  157. <tr>
  158. <td>
  159. New Recovered
  160. </td>
  161. <td>
  162. {{selectedCountryData?.NewRecovered | number}}
  163. </td>
  164. </tr>
  165. <tr>
  166. <td>
  167. Total Recovered
  168. </td>
  169. <td>
  170. {{selectedCountryData?.TotalRecovered | number}}
  171. </td>
  172. </tr>
  173. <tr>
  174. <td>
  175. New Confirmed
  176. </td>
  177. <td>
  178. {{selectedCountryData?.NewConfirmed | number}}
  179. </td>
  180. </tr>
  181. <tr>
  182. <td>
  183. Total Confirmed
  184. </td>
  185. <td>
  186. {{selectedCountryData?.TotalConfirmed | number}}
  187. </td>
  188. </tr>
  189. <tr>
  190. <td>
  191. New Deaths
  192. </td>
  193. <td>
  194. {{selectedCountryData?.NewDeaths | number}}
  195. </td>
  196. </tr>
  197. <tr>
  198. <td>
  199. Total Deaths
  200. </td>
  201. <td>
  202. {{selectedCountryData?.TotalDeaths | number}}
  203. </td>
  204. </tr>
  205. </table>
  206. </mat-card-content>
  207. </mat-card>
  208. </div>
  209. </div>
  210. <div>
  211. <div class="same-row table-data">
  212. <p style="font-weight: bold; color: darkgreen; font-size: large;">Highest Recovered Cases</p>
  213. <table>
  214. <tr>
  215. <td style="font-weight: bold;">
  216. Sl.No.
  217. </td>
  218. <td style="font-weight: bold;">
  219. Country
  220. </td>
  221. <td style="font-weight: bold;">
  222. Total Recovered
  223. </td>
  224. </tr>
  225. <tr *ngFor="let country of highlyRecoveredData; let i=index">
  226. <td>
  227. {{i+1}}
  228. </td>
  229. <td>
  230. {{country.Country}}
  231. </td>
  232. <td>
  233. {{country.TotalRecovered | number}}
  234. </td>
  235. </tr>
  236. </table>
  237. </div>
  238. <div class="same-row table-data">
  239. <p style="font-weight: bold; color:gray; font-size: large;">Highest Confirmed Cases</p>
  240. <table>
  241. <tr>
  242. <td style="font-weight: bold;">
  243. Sl.No.
  244. </td>
  245. <td style="font-weight: bold;">
  246. Country
  247. </td>
  248. <td style="font-weight: bold;">
  249. Total Confirmed
  250. </td>
  251. </tr>
  252. <tr *ngFor="let country of highlyConfirmedData; let i=index">
  253. <td>
  254. {{i+1}}
  255. </td>
  256. <td>
  257. {{country.Country}}
  258. </td>
  259. <td>
  260. {{country.TotalConfirmed | number}}
  261. </td>
  262. </tr>
  263. </table>
  264. </div>
  265. <div class="same-row table-data">
  266. <p style="font-weight: bold; color: indianred; font-size: large;">Highest Death Cases</p>
  267. <table>
  268. <tr>
  269. <td style="font-weight: bold;">
  270. Sl.No.
  271. </td>
  272. <td style="font-weight: bold;">
  273. Country
  274. </td>
  275. <td style="font-weight: bold;">
  276. Total Deaths
  277. </td>
  278. </tr>
  279. <tr *ngFor="let country of highlyDeathData; let i=index">
  280. <td>
  281. {{i+1}}
  282. </td>
  283. <td>
  284. {{country.Country}}
  285. </td>
  286. <td>
  287. {{country.TotalDeaths | number}}
  288. </td>
  289. </tr>
  290. </table>
  291. </div>
  292. </div>
We have used Angular material select component to list the country name and also used material card to display Covid-19 data. We have used some inline styles inside the html file but that is not advisable. I will cleanup this code very soon and remove these inline styles from html file.
We can add some css class details inside the app.component.css file.
app.component.css
  1. .covid-card {
  2. max-width: 350px;
  3. }
  4. .same-row {
  5. display: inline-block;
  6. padding: 10px;
  7. }
  8. .table-data {
  9. padding: 10px;
  10. margin: 10px;
  11. }
  12. table {
  13. padding: 10px;
  14. width: 300px;
  15. border: 1px solid gray;
  16. background-color: honeydew;
  17. }
  18. tr {
  19. margin: 10px;
  20. padding: 10px;
  21. }
  22. td {
  23. height: 30px;
  24. vertical-align: center;
  25. border: 1px dotted gray;
  26. }
We have successfully built our Covid-19 tracker application in short time. We can run the application now.
Create Simple COVID-19 Tracker With Angular 10 And Material Design
We have showed Global summary, Indian country summary along with top 10 highest recovered, highest confirmed and highest death cases.
User can choose the country name from the material list box.
Create Simple COVID-19 Tracker With Angular 10 And Material Design
After choosing a country name, we can get the data for that particular country in below card.
Create Simple COVID-19 Tracker With Angular 10 And Material Design
I have deployed this application to Google firebase and you can use this LIVE app to track Covid-19 data.

Conclusion


In this post, we have seen how to create a simple Covid-19 tracker app with Angular 10 using Material design. We have used https://covid19api.com/ free API service to fetch live data. We have provided an option to choose any country name and get data of that country. We have also provided the highest 10 recovered, highest confirmed, and highest death cases. If anybody is interested, we can tweak this application with more features like data analysis using some charts as well. Please feel free to provide the feedback about this application.