I am trying build a basic currency converter and having issues binding the selected option and displaying its value in the input
<template>
<div >
<h1 >
Currency Converter
</h1>
<div >
<input v-model="currencyValue" type="number">
<select>
<option v-for="Currency in currencyName" :key="Currency">
{{ Currency }}
</option>
</select>
</div>
=
<div >
<input v-model="currencyValue" type="number">
<select>
<option v-for="Currency in currencyName" :key="Currency">
{{ Currency }}
</option>
</select>
</div>
</div>
</template>
<script>
export default {
data() {
return {
listItems: [],
currencyName: [],
currencyValue: []
}
},
methods: {
async getData() {
const res = await fetch("https://api.exchangerate.host/latest");
const finalRes = await res.json();
this.listItems = finalRes.rates;
this.currencyName = Object.keys(this.listItems)
this.currencyValue = Object.values(this.listItems)
console.log(this.currencyName);
console.log(this.currencyValue);
console.log(this.listItems);
}
},
mounted() {
this.getData()
}
}
</script>
I tried using a v-model on the input however I still seem to be needing more to loop through the values in the object from the API
CodePudding user response:
Why bind the entire array of exchange rate values to an input (to both inputs actually)? Assuming the first input is for a user to input an amount that you will then convert, the v-model should be a unique variable initialized as null or 0, not with your API data. Also, each input/select that the user can interact with should have it's own unique v-model to provide 2-way binding. Any inputs sharing the same v-model are always going to share and display the exact same value. Any "output" field where you only want to display a result (not have the user change/interact with it) should use just 1-way binding with the :value=
property.
Not to write the entire component for you, I've made this codesandbox that should help you get the right idea
CodePudding user response:
As per my understanding, You want to fill the input fields based on the currency name selected in the select. If Yes, Here are few observations as per your code :
- You are passing whole array of currency values in a
v-model
of input, It should be a single value based on the currency name selection. Hence, you have to add the@change
event on dropdown and based on the value update the input field v-model. - I did not see any v-model to the select. It should be there to capture the selected currency name.
- Input fields should be read only as you are not doing any calculations on currency. I think user input is not required.
listItems
is an object, hence it should be initialized as{}
not[]
.
Live Demo :
new Vue({
el: '#app',
data() {
return {
listItems: {},
currencyName: [],
currencyValue1: '',
currencyValue2: '',
selectedCurrency1: '',
selectedCurrency2: ''
}
},
methods: {
async getData() {
const res = await fetch("https://api.exchangerate.host/latest");
const finalRes = await res.json();
this.listItems = finalRes.rates;
this.currencyName = Object.keys(this.listItems)
this.currencyValue = Object.values(this.listItems)
},
getCurrValue1() {
this.currencyValue1 = this.listItems[this.selectedCurrency1];
},
getCurrValue2() {
this.currencyValue2 = this.listItems[this.selectedCurrency2];
}
},
mounted() {
this.getData()
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1 >
Currency Converter
</h1>
<div >
<input v-model="currencyValue1" type="number" disabled>
<select v-model="selectedCurrency1" @change="getCurrValue1">
<option disabled value="">Select Currency</option>
<option v-for="Currency in currencyName" :value="Currency" :key="Currency">
{{ Currency }}
</option>
</select>
</div>
=
<div >
<input v-model="currencyValue2" type="number" disabled>
<select v-model="selectedCurrency2" @change="getCurrValue2">
<option disabled value="">Select Currency</option>
<option v-for="Currency in currencyName" :value="Currency" :key="Currency">
{{ Currency }}
</option>
</select>
</div>
</div>