Home > Back-end >  Format data from API
Format data from API

Time:10-26

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
    }
}
  • Related