Hi I'm learning angular and I want to make a currency converter using angular reactive form,I figured out the form itself, all the fields are readable, but after a request to the backend, the answer does not come, tell me what I'm doing wrong?
this is my html
<div >
<form [formGroup]="currencyForm"
class ="form-box">
<div >
<input type="text"
formControlName="amount">
<select name="" id="country1" formControlName="changebase">
<option value="USD">US dollar</option>
<option value="EUR">Euro</option>
<option value="UAH">Ukranian Grivna</option>
</select>
</div>
<p > to </p>
<select name="" id="country1" formControlName="tocountry">
<option value="USD">US dollar</option>
<option value="EUR">Euro</option>
<option value="UAH">Ukranian Grivna</option>
</select>
<button (click)="convert()"> Submit</button>
</form>
<div >
<p >{{changebase}} <span>=</span>{{result}} {{tocountry}}</p>
</div>
</div>
This is my request
import { Injectable } from '@angular/core';
import {HttpClient} from "@angular/common/http"
@Injectable({
providedIn: 'root'
})
export class CurrencydataService {
constructor(private http:HttpClient) { }
getcurrencydata(country1:string){
let url ="https://api.exchangerate.host/latest?base=USD" country1
return this.http.get(url)
}
}
This is my logic
export class CurrencyReactiveComponent implements OnInit {
currjson:any="";
amount:number=1;
changebase:string= "";
tocountry:string="";
result:number=1
createFormGroup(){
return new FormGroup({
amount: new FormControl(""),
changebase: new FormControl(""),
tocountry:new FormControl("")
});
}
currencyForm: FormGroup;
constructor(private currency:CurrencydataService) {
this.currencyForm =this.createFormGroup()
}
ngOnInit() {
//this.getcurrencydata()
}
convert(){
this.currency
.getcurrencydata(this.changebase)
.subscribe(data=>{
this.currjson= JSON.stringify(data);
this.currjson= JSON.parse(this.currjson);
console.log(this.currencyForm.value)
if (this.tocountry ==="USD"){
this.result = this.currjson.rates.USD * (this.amount)
}
if (this.tocountry ==="EUR"){
this.result = this.currjson.rates.EUR * (this.amount)
}
if (this.tocountry ==="UAH"){
this.result = this.currjson.rates.UAH * (this.amount)
}
})
}
}
Please, help me to understand what i am doing bad
CodePudding user response:
For explanation purpose I put everything in the component
Here is a stackblitz if you want to check it out
In your getcurrencydata
you are not taking country into account you need to change it to
getcurrencydata(country: string) {
const url = `https://api.exchangerate.host/latest?base=${country}`;
return this.http.get<ICurrencyResponse>(url);
}
Then I would change couple things to use rxjs
In the component I would have something like
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { Observable, of, switchMap } from 'rxjs';
interface ICurrencyResponse {
motd: {
msg: string;
url: string;
};
success: boolean;
base: string;
date: Date;
rates: {
[key: string]: number;
};
}
@Component({
imports: [CommonModule, ReactiveFormsModule],
standalone: true,
selector: 'memento-stackoverflow',
templateUrl: './stackoverflow.component.html',
})
export class StackoverflowComponent {
public value$: Observable<number>;
currencyForm = new FormGroup({
amount: new FormControl(10),
originCountry: new FormControl('USD'),
targetCountry: new FormControl('EUR'),
});
constructor(private http: HttpClient) {
this.convert();
}
getcurrencydata(country: string) {
const url = `https://api.exchangerate.host/latest?base=${country}`;
return this.http.get<ICurrencyResponse>(url);
}
convert() {
if (
this.currencyForm.value.originCountry &&
this.currencyForm.value.targetCountry &&
this.currencyForm.value.amount
) {
this.value$ = this.getcurrencydata(
this.currencyForm.value.originCountry
).pipe(
switchMap((response) => {
return of(
response.rates[this.currencyForm.value.targetCountry as string] *
(this.currencyForm.value.amount as number)
);
})
);
}
}
}
In the template
<div >
<form [formGroup]="currencyForm" >
<div >
<input type="text" formControlName="amount" />
<select formControlName="originCountry">
<option value="USD">US dollar</option>
<option value="EUR">Euro</option>
<option value="UAH">Ukranian Grivna</option>
</select>
</div>
<p >to</p>
<select formControlName="targetCountry">
<option value="USD">US dollar</option>
<option value="EUR">Euro</option>
<option value="UAH">Ukranian Grivna</option>
</select>
</form>
<button (click)="convert()">Submit</button>
<div >
<p ><span>=</span>{{ value$ | async }}</p>
</div>
</div>
CodePudding user response:
You are not using the forms value, you are using class fields, which are never assigned.
Change to and try again:
export class CurrencyReactiveComponent implements OnInit {
currjson:any="";
result:number=1
createFormGroup(){
return new FormGroup({
amount: new FormControl(""),
changebase: new FormControl(""),
tocountry:new FormControl("")
});
}
currencyForm: FormGroup;
constructor(private currency:CurrencydataService) {
this.currencyForm =this.createFormGroup()
}
convert(){
this.currency
.getcurrencydata(this.currencyForm.get('changebase').value)
.pipe(take(1))
.subscribe(data=>{
this.currjson = data;
console.log(this.currencyForm.value)
this.result = this.currjson.rates[(this.currencyForm.get('tocountry').value]
* (this.currencyForm.get('amount').value);
}
}