IONIC 6 CURRENCY CONVERTER | FOREIGN EXCHANGE RATES APPS TUTORIAL – PART 1

Ionic 6 exchange rates and currency conversion aps; In this tutorial, we will build an application that works to display currency conversions and exchange rates based on the selected country. An exchange rate is the rate at which one currency can be exchanged for another between nations or economic zones. It is used to determine the value of various currencies in relation to each other and is important in determining trade and capital flow dynamics.

We will use the free API from Exchangerate which is a simple and lightweight free service for current and historical foreign exchange rates & crypto exchange rates. For this tutorial we will use only the Latest Rate API. Besides, this tutorial will explain how to create a basic Ionic Angular currency converter app using the Exchangerate API through the HTTP client module API.

HOW TO BUILD THE CURRENCY CONVERTER IN IONIC – PART 1

  • Step 1 : Create new Ionic Project
  • Step 2 : Build service to integrate fetch the data using API
  • Step 3 : Create the currency selector and amount input
  • Step 4 : Customize the interface (Optional in Part 2)
CREATE NEW IONIC PROJECT

Let us full fill the first requirement that is to install the latest version of Ionic CLI.

npm install -g @ionic/cli

Use command to create the Ionic Angular app:

ionic start currency-converter blank --type=angular 

Get into the project root directory:

cd currency-converter
BUILD SERVICE TO INTEGRATE WITH THE API

To create a service in the Angular apps, just simply run the command below:

ionic generate service services/data

We need to create a function that will fetch available symbols / currency from the provided API using HTTP Methods. To use HTTP Methods we will need to setup a few thing first.

Go to src/app/app.modules.ts and import the HttpClientModule.

import { HttpClientModule } from '@angular/common/http';
@NgModule({
  declarations: [...],
  entryComponents: [...],
  imports: [
    HttpClientModule
  ],
  providers: [...],
  bootstrap: [...],
})
export class AppModule {}

Then go to src/app/services/data.service.ts and write the code below.

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class DataService {
  symbols = 'https://api.exchangerate.host/symbols';
  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
    })
  };

  constructor(private httpClient: HttpClient) { }

  getSymbols() {
    return new Promise(resolve => {
      this.httpClient.get(this.symbols, this.httpOptions).subscribe((data: any) => {
        resolve(data);
        console.log(data);
      }, err => {
        console.log(err);
      });
    });
  }

}

It will return the available symbols like below at the log.

CREATE THE CURRENCY SELECTOR AND AMOUNT INPUT

Go to src/app/home/home.page.html and edit the code like below.

<ion-content [fullscreen]="true">
   <ion-header>
      <ion-toolbar>
         <ion-title>FOREIGN EXCHANGE RATES</ion-title>
      </ion-toolbar>
   </ion-header>
   <div id="slcContainer">
      <ion-row>
         <ion-col size="12" size-md>
            <div class="titleSelect">Enter amount</div>
            <ion-item>
               <ion-input [(ngModel)]="curAmount" type="number" inputmode="decimal"></ion-input>
            </ion-item>
         </ion-col>
         <ion-col size="12" size-md>
            <div class="titleSelect">Select Currency</div>
            <div style="display: flex;">
               <ion-searchbar showClearButton="never" (ionFocus)="isOpen=true" id="searchCurr" placeholder=" Select a currency" value="{{seleCur}}"></ion-searchbar>
            </div>
         </ion-col>
      </ion-row>
      <ion-modal [isOpen]="isOpen" (didDismiss)="isOpen=false">
      <ng-template>
         <ion-header>
            <ion-toolbar>
               <ion-title>Select a currency</ion-title>
               <ion-buttons slot="end">
                  <ion-button (click)="isOpen=false">Close</ion-button>
               </ion-buttons>
            </ion-toolbar>
         </ion-header>
         <ion-content>
            <ion-list>
               <ion-radio-group (ionChange)="selectedCur($event)" value="USD">
                  <ion-list-header>
                     <ion-label>Name</ion-label>
                  </ion-list-header>
                  <ion-item *ngFor="let i of symbols">
                     <ion-label>{{i.code}} - {{i.desc}}</ion-label>
                     <ion-radio slot="start" value="{{i.code}}|{{i.desc}}"></ion-radio>
                  </ion-item>
               </ion-radio-group>
            </ion-list>
         </ion-content>
      </ng-template>
      </ion-modal>
   </div>
</ion-content>

Now we will edit the src/app/home/home.page.ts. Here we will create a function that firing the function on the data.services that we created before to get the available symbols as stored data for our ion-radio.

import { Component, OnInit } from '@angular/core';
import { DataService } from "../services/data.service";
@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  symbols: any;
  curAmount: any = '1.00';
  constructor(private dataServer: DataService) {}
  ngOnInit() {
    this.getSymbols();
  }

  // INITIAL
  async getSymbols() {
    await this.dataServer.getSymbols().then((data: any) => {
      this.symbols = [];
      for (var key in data.symbols) {
        if (data.symbols.hasOwnProperty(key)) {
          this.symbols.push({ "code": data.symbols[key].code, "desc": data.symbols[key].description });
        }
      }
    });
  }
  selectedCur(ev) {
    let selCur = ev.detail.value;
    let a = selCur.split("|");
  }
}

If we done it correctly, a modal with list of currency will appear when we click the input like example below.

Next, we will create the conversion function base on the amount/value of selected currency using the provided API. With the same method we will make the function to interact with the API in the data.service.ts page.

Go back to src/app/services/data.service.ts and add the new function like below :

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class DataService {
  symbols = 'https://api.exchangerate.host/symbols';
  rates = 'https://api.exchangerate.host/latest?base=';
  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
    })
  };
  constructor(private httpClient: HttpClient) { }

  getSymbols() {
    return new Promise(resolve => {
      this.httpClient.get(this.symbols, this.httpOptions).subscribe((data: any) => {
        resolve(data);
      }, err => {
        console.log(err);
      });
    });
  }

  convCur(base, amount) {
    return new Promise(resolve => {
      let newRates = this.rates + base + '&amount=' + amount;
      this.httpClient.get(newRates, this.httpOptions).subscribe((data: any) => {
        resolve(data);
      }, err => {
        console.log(err);
      });
    });
  }

}

As we see, this function take 2 parameter which the base/symbols of currency and the amount to be pass as parameter for the API. Now, we will call this function to get the result and display the result of the conversion.

Go back to src/app/home/home.page.ts. and add the new function like below :

import { Component, OnInit } from '@angular/core';
import { DataService } from "../services/data.service";
import { LoadingController } from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  symbols: any;
  codeCur: any = '';
  descCur: any;
  seleCur: any;
  convData: any = [];
  ratesData: any = [];
  curAmount: any = '1.00';

  constructor(
    private dataServer: DataService,
    public loader: LoadingController ){}

  ngOnInit() {
    this.getSymbols();
  }

// INITIAL
  async getSymbols() {
    await this.dataServer.getSymbols().then((data: any) => {
      this.symbols = [];
      for (var key in data.symbols) {
        if (data.symbols.hasOwnProperty(key)) {
          this.symbols.push({ "code": data.symbols[key].code, "desc": data.symbols[key].description });
        }
      }
    });
  }

  async convertCurrency(base, amount) {
    await this.dataServer.convCur(base, amount).then((data: any) => {
      this.ratesData = Object.keys(data.rates)
        .map(key => ({ name: key, value: data.rates[key] }))
    });
    this.convData = [];
    for (let i = 0; i < this.symbols.length; i++) {
      this.convData.push({
        ...this.symbols[i],
        ...(this.ratesData.find((itmInner) => itmInner.name === this.symbols[i].code))
      }
      );
    }
  }

  async getRates() {
    const loading = await this.loader.create({
      message: 'Changing the currency',
      duration: 2000
    });
    await loading.present();
    await this.convertCurrency(this.codeCur, this.curAmount);
  }

  selectedCur(ev) {
    let selCur = ev.detail.value;
    let a = selCur.split("|");
    this.codeCur = a[0];
    this.descCur = a[1];
    this.seleCur = a[0] + ' - ' + a[1];
  }
}

Now we already have the data of the conversion result, to display it just add this code in src/app/home/home.page.html

<ion-content [fullscreen]="true">
    <ion-header>
        <ion-toolbar>
            <ion-title>FOREIGN EXCHANGE RATES</ion-title>
        </ion-toolbar>
    </ion-header>
    <div id="slcContainer">
        <ion-row>
            <ion-col size="12" size-md>
                <div class="titleSelect">Enter amount</div>
                <ion-item>
                    <ion-input [(ngModel)]="curAmount" type="number" inputmode="decimal"></ion-input>
                </ion-item>
            </ion-col>
            <ion-col size="12" size-md>
                <div class="titleSelect">Select Currency</div>
                <div style="display: flex;">
                    <ion-searchbar showClearButton="never" (ionFocus)="isOpen=true" id="searchCurr" placeholder=" Select a currency" value="{{seleCur}}"></ion-searchbar>
                </div>
            </ion-col>
        </ion-row>
        <ion-button expand="block" (click)="getRates()">Convert</ion-button>
        <ion-modal [isOpen]="isOpen" (didDismiss)="isOpen=false">
            <ng-template>
                <ion-header>
                    <ion-toolbar>
                        <ion-title>Select a currency</ion-title>
                        <ion-buttons slot="end">
                            <ion-button (click)="isOpen=false">Close</ion-button>
                        </ion-buttons>
                    </ion-toolbar>
                </ion-header>
                <ion-content>
                    <ion-list>
                        <ion-radio-group (ionChange)="selectedCur($event)" value="USD">
                            <ion-list-header>
                                <ion-label>Name</ion-label>
                            </ion-list-header>
                            <ion-item *ngFor="let i of symbols">
                                <ion-label>{{i.code}} - {{i.desc}}</ion-label>
                                <ion-radio slot="start" value="{{i.code}}|{{i.desc}}"></ion-radio>
                            </ion-item>
                        </ion-radio-group>
                    </ion-list>
                </ion-content>
            </ng-template>
        </ion-modal>
        <div>
            <ion-card *ngFor="let d of convData">
                <div class="listRates">
                    <div class="ratesDetails">
                        <ion-card-subtitle>
                            {{d.name}} - {{d.desc}}
                        </ion-card-subtitle>
                        <ion-card-subtitle style="color:green;">
                            {{d.value}}
                        </ion-card-subtitle>
                    </div>
                </div>
            </ion-card>
        </div>
    </div>
</ion-content>

If everything is good, we already have a functioning app that make conversion like video below.

Go to Part 2.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *