I am trying to build an currency exhanger app using an API. When I try to get the first currency, i get indexOutOfBounds Exception. I know that exchangeDetails Array empty is and i cannot reach to an empty array. But i dont know how to fix it.
This is CalculateView
Column {
if(calculateViewModel.loading){
CircularProgressIndicator()
}else{
Text(text = calculateViewModel.exchangeDetail[0].get("EUR").toString())
Text(text = calculateViewModel.exchangeDetail[0].get(currency2).toString())
}
}
and this is CalculateViewModel
class CalculateViewModel: ViewModel() {
private val exchangeService = ExchangeService()
var loading: Boolean by mutableStateOf(false)
var errorMessage : String by mutableStateOf("")
var exchangeDetail : MutableList<Map<String, Float>> by mutableStateOf(mutableListOf())
fun getExchangeRatio(input1: String, input2: String) = viewModelScope.launch {
errorMessage = ""
loading = true
try {
val ratio = exchangeService.getExchangeCourse(input1,input2)
exchangeDetail.add(ratio.data)
}catch (e: Exception){
errorMessage = e.message.toString()
}finally {
loading = false
}
}
}
exhchangeDto class
@kotlinx.serialization.Serializable
data class ExchangeDto (
val data: Map<String, Float>
//Zugriff über .get()
)
APIManager
class APIManager {
private val apiKey = "Om1xoJkPAxk9neFbFvzezQtxAuNHdSERTfN8CPbk"
var jsonHttpClient = HttpClient {
expectSuccess = true
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
defaultRequest {
url.host = "api.freecurrencyapi.com"
url.protocol = URLProtocol.HTTPS
url.encodedPath = "/v1/latest?apikey=$apiKey" + url.encodedPath
contentType(ContentType.Application.Json)
headers {
append(HttpHeaders.Authorization,
"Bearer $apiKey")
}
}
HttpResponseValidator {
getCustomResponseValidator(this)
}
}
}
Thanks...
I tried to get the currency value from an array list, i was expecting to call it via get() function. I got IndexOutOfBounds error.
There is several ways to avoid error here.
One way could be to use the firstOrNull method instead of accessing it using [0]
if(calculateViewModel.loading){
CircularProgressIndicator()
}else{
Text(text = calculateViewModel.exchangeDetail.firstOrNull()?.get("EUR")?.toString() ?: "")
Text(text = calculateViewModel.exchangeDetail.firstOrNull()?.get(currency2)?.toString() ?: "")
}
Note that with this " fix " you need to have a default value (empty string here). You can change it for whatever you like.
One other way could be to check if the array is empty or not before trying to print those texts.
if(calculateViewModel.loading){
CircularProgressIndicator()
}else{
if(calculateViewModel.exchangeDetail.isNotEmpty()) {
Text(text = calculateViewModel.exchangeDetail[0].get("EUR").toString())
Text(text = calculateViewModel.exchangeDetail[0].get(currency2).toString())
} else {
// print whatever you want ...
}
}