0

I am trying to create a currency converter application similar to the one that Google has i.e

enter image description here

My challenge is that the data I have to work with which comes from fixer.io needs to be reworked in order to accomplish the above Google converter. I can only use the following endpoint from fixer.io which is http://data.fixer.io/api/latest?access_key=.....

My code below may explain a bit better. I have also created a stackblitz here https://stackblitz.com/edit/angular-9-material-starter-o9yvuu?file=src/app/app.component.ts

Service

//list endpoint from Fixer.io
currencyRates(): Observable<any> {
    return this.http.get(this.baseURL + this.accessKey);
}

TS

  //call endpoint and manipulate data to use on HTML
  public currencies: any;
  public currenciesArr: any;

  getCurrencies() {
    this.currencyService.currencyRates().subscribe({
      next: (v) => {
        this.currencies = v;
        let result = Object.keys(this.currencies.rates).map((key) => 
          [String(key), this.currencies.rates[key]]
        );
        this.currenciesArr = result;
        console.log(this.currenciesArr);
      },
      error: (e) => console.error(e),
      complete: () => console.info('complete') 
   });
  }

HTML

    <mat-form-field class="form-field" appearance="outline">
      <mat-label> Input Currency
      </mat-label>
      <input matInput formControlName="input" required>
    </mat-form-field>
    <mat-form-field appearance="fill">
        <mat-label>Select an option</mat-label>
        <mat-select >
          <mat-option *ngFor="let item of currenciesArr" [value]="item">{{item}}</mat-option>
        </mat-select>
    </mat-form-field>
    <mat-form-field class="form-field" appearance="outline">
      <mat-label> Output Currency
      </mat-label>
      <input matInput formControlName="output" type="output" required>
    </mat-form-field>
    <mat-form-field appearance="fill">
      <mat-label>Select an option</mat-label>
      <mat-select >
        <mat-option *ngFor="let item of currenciesArr" [value]="item">{{item}}</mat-option>
      </mat-select>
  </mat-form-field>

The data that originally came from the endpoint looked like below which I subsequently converted in order to use in my dropdown boxes. Converting it in my TS using Object.keys.

{
    "success": true,
    "timestamp": 1645249562,
    "base": "EUR",
    "date": "2022-02-19",
    "rates": {
        "AED": 4.158769,
        "AFN": 104.057478,
        "ALL": 121.54654
    }
}

I am now confused as to how to manipulate the data further so that I can show the currency name in the dropdowns and the actual value of the currency in the input fields. Can anyone please help me here?

I am currently thinking that I need to create 2 arrays. Once for the currency name, the other for the value but I am so lost.

skydev
  • 1,867
  • 9
  • 37
  • 71
  • Do you get your rates as that structure you posted (last block) or like: `{ "success": true, "timestamp": 1620386223, "source": "GBP", "quotes": { "GBPAED": 5.109727, "GBPAFN": 107.750768, "GBPALL": 141.659078, "GBPAMD": 725.255305,`...? – Misha Mashina Feb 19 '22 at 06:29
  • @MishaMashina Yes, that is how I get rates from the service. Here is the actual service call with a free access key for reference `http://data.fixer.io/api/latest?access_key=1a1391b6ede21fa90a4789f8e80a2973` – skydev Feb 19 '22 at 06:35
  • 1
    @skydev `I can show the currency name in the dropdowns and the actual value of the currency in the input fields` means ? – GRD Feb 19 '22 at 06:37
  • Aha, I checked now. So you get it from https://exchangeratesapi.io/? Have you checked their documentation? They have conversion endpoint too: https://exchangeratesapi.io/documentation/#convertcurrency and it would make it much easier for you. – Misha Mashina Feb 19 '22 at 06:38
  • @MishaMashina Yes, I did see that but unfortunately I can't use that and it is also not part of the free plan. But if showing currency names in the dropdowns and the actual value of the currency in the input fields is possible with the standard service `http://data.fixer.io/api/latest?access_key=1a1391b6ede21fa90a4789f8e80a2973` it would be great – skydev Feb 19 '22 at 06:40
  • @GRD essentially per how the google currency converter works – skydev Feb 19 '22 at 06:50
  • @GRD Yes, that is correct for the dropdown. Then on the corresponding input field I need to show the value for the selected currency – skydev Feb 19 '22 at 07:23
  • @GRD This is working better. It only needs to change the currency values when the user types a value in the first dropdown then the second dropdown changes to a new value eg. First dropdown has 1 AED, then second dropdown gets 3.4 AFN(or whatever the exchange rate is) – skydev Feb 19 '22 at 07:43
  • @GRD Actually the preset is EURO so the one dropdown will have to be fixed to EURO. So essentially only one dropdown will be changeable – skydev Feb 19 '22 at 07:46

1 Answers1

0

Ok, so that data you have is enough, you just need some gymnastics :)

FIrst, I'd make an array (for example: allCurrencies) of currency objects, each having the structure: { currency: 'XYZ', baseRate: '1234' } where 'XYZ' would be names of currencies taken from your 'rates' field, and '1234' would be a conversion value of the given currency (Against EUR).

Second, in template I'd iterate over that array and set dropdown options to 'currency' values. Optionally, I'd make output currency input field readonly.

Third, when 'input currency' is changed/set and the corresponding text input is not empty/null, I'd immediately (in .ts) convert the amount to EUR, based on allCurrencies 'baseRate' for that 'currency'. Let's call this new amount convertedOriginal.

Fourth, when the 'output currency' is changed (and if 'input currency' is picked and the corresponding text input is not empty/null), I'd convert the convertedOriginal value to selected output currency's rate.

Misha Mashina
  • 1,739
  • 2
  • 4
  • 10