Soumik Bhattacharjee
Soumik Bhattacharjee

Reputation: 945

How to rename the key of a JSON Response dynamically in Retrofit2 Android

I have a JSON response like this:

    {
        "AED_BDT": 23.100486
    }

But the key changes according to my query like if my query is USD_BDT, then it will give response like this:

 {
        "USD_BDT": 23.100486
 }

So,that means I need to change the JSON key according to my query. But I couldn't find any solution on how to do this.

I tried by converting the response body into String and then replaced the Key according to my query, but this is not working..

This is my model class:

data class ResponseCurrencyConvert(
    val USD_BDT: Double
)

This is what I tried so far:

val params = HashMap<String,String>()
        params["compact"]="ultra"
        params["apiKey"]= API_KEY
        params["q"]="${currencyFrom}_${currencyTo}"//getting specific currencies and then setting them as query,i.e:USD_BDT
        message(TAG,"Query: ${params["q"]}")
        prefManager.query=params["q"]!!

        //calling the API
        apiServices.convertCurrency(params).enqueue(object : Callback<ResponseCurrencyConvert>{
            override fun onFailure(call: Call<ResponseCurrencyConvert>, t: Throwable) {
                message(TAG,"onFailure: ${t.localizedMessage}")
            }

            override fun onResponse(call: Call<ResponseCurrencyConvert>, response: Response<ResponseCurrencyConvert>) {
               message(TAG,"onResponse Code: ${response.code()}")
               message(TAG,"onResponse Body: ${Gson().toJson(response.body())}")

                val json = Gson().toJson(response.body())//converting the response as string
                val oldValue = "USD_BDT"//the key which was in my model class
                val newValue=params["q"]// the new key which is my query
                val output = json.replace(oldValue,newValue!!,false) // replacing the default query with my query
                val newResponse = Gson().fromJson(output,ResponseCurrencyConvert::class.java)//again converting the new replaced string to json

                    if (response.isSuccessful){

                    message(TAG,"Output: $output")
                    message(TAG,"onResponse Result: ${newResponse?.USD_BDT}")
                    message(TAG,"onResponse newResult: ${newResponse.USD_BDT}")
                    rate= newResponse?.USD_BDT//getting the value; this is returning 0 every time expect when my query is USD_BDT

I commented everything that I did on the code, please read that carefully. Your help is highly appreciated..

Upvotes: 1

Views: 1392

Answers (3)

Francesco Re
Francesco Re

Reputation: 836

A way to do that is maintaining the 2 different keys, which is the most simple and effective.

Another way to accomplish this is changing the Response type to string. When you get the response you change the JSON string, changing the key name and then use GSON to manually convert from JSON to Object.

Maybe it can be done also with a Custom Json Converter, but I don't think is worth.

Upvotes: 0

Shrikant
Shrikant

Reputation: 589

If the key changes for every other response, I would suggest using HashMap<String, String>. Instead of mapping directly to String value which changes dynamically using HashMap would solve your issue.

Let me know how it goes.

Upvotes: 0

drjansari
drjansari

Reputation: 326

Keys are defined from the server only I guess

The best way you can do is like keep both keys and make it nullable

else you have an alternate name in JSON parsing

Upvotes: 1

Related Questions