I'm currently writing a currency converter app. Everything is working fine however I'm having trouble formatting the API response. I'm getting "CurrencyResponse(conversion_result=1)" when what I really want is to get the value of conversion_result alone.
Below is the relevant code.
Thank you.
CurrencyApi.kt
package com.example.currencyconverter.data
import com.example.currencyconverter.BuildConfig
import retrofit2.http.GET
import retrofit2.http.Path
interface CurrencyApi {
companion object {
const val BASE_URL = "https://v6.exchangerate-api.com/v6/"
}
@GET("{access_key}/pair/{currency_from}/{currency_to}/{amount}")
suspend fun convert(
@Path("access_key") access_key: String = BuildConfig.API_KEY,
@Path("currency_from") currency_from: String,
@Path("currency_to") currency_to: String,
@Path("amount") amount: Double? = 0.0
): CurrencyResponse
}
CurrencyResponse.kt
package com.example.currencyconverter.data
import com.squareup.moshi.Json
data class CurrencyResponse(
@Json(name="conversion_result") var conversion_result: String
){
}
CurrencyRepository.kt
package com.example.currencyconverter.data
import com.example.currencyconverter.BuildConfig
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class CurrencyRepository @Inject constructor(private val currencyApi: CurrencyApi) {
suspend fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?): CurrencyResponse {
return currencyApi.convert(BuildConfig.API_KEY, baseCurrency, toCurrency, amount)
}
}
CurrencyViewModel.kt
package com.example.currencyconverter.ui
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.currencyconverter.data.CurrencyRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class CurrencyViewModel @Inject constructor(private val repository: CurrencyRepository): ViewModel() {
private val _conversionResult = MutableLiveData<String>()
val conversionResult: LiveData<String> = _conversionResult
fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?) {
viewModelScope.launch {
_conversionResult.value = repository.getConversionRate(baseCurrency, toCurrency, amount).toString()
}
}
}
HomeFragment.kt
package com.example.currencyconverter.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.currencyconverter.R
import com.example.currencyconverter.databinding.FragmentHomeBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class HomeFragment : Fragment(R.layout.fragment_home) {
private val viewModel by viewModels<CurrencyViewModel>()
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentHomeBinding.bind(view)
lateinit var firstCurrency: String
lateinit var secondCurrency: String
binding.apply {
spinnerFirst.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
firstCurrency = adapterView?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
spinnerSecond.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
secondCurrency = adapterView?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
}
binding.button.setOnClickListener {
val stringInTextField = binding.amountText.text.toString()
val amount = stringInTextField.toDoubleOrNull()
if(amount==null) {
binding.resultText.text = " "
}
viewModel.getConversionRate(firstCurrency, secondCurrency, amount)
viewModel.conversionResult.observe(viewLifecycleOwner) {
binding.resultText.text = it
}
}
}
}
CodePudding user response:
The problem lies in
fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?) {
viewModelScope.launch {
_conversionResult.value = repository.getConversionRate(baseCurrency, toCurrency, amount).toString()
}
}
to call toString()
on a data class formats it the way you see it.
Since you only want the conversion_result you need to change it to
fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?) {
viewModelScope.launch {
_conversionResult.value = repository.getConversionRate(baseCurrency, toCurrency, amount).conversion_result
}
}