Search code examples
androidjsonkotlinretrofit

How can I parse a specific key from JSON and map it to a class using Retrofit?


I am new to Retrofit and I am trying to fetch a JSON from an API and display it in my RecylerView. But the problem is the JSON I fetched has two keys, namely result and offers as shown below.

{"result":true,"offers":[{"lmd_id":"1285747","store":"box8.in","merchant_homepage":"https:\/\/box8.in\/","offer_text":"Free Chocolava Cake on All Orders","offer_value":"Free","title":"Free Chocolava Cake","description":"This voucher is applicable on All Orders (On minimum order of ₹450)","code":"","terms_and_conditions":"","categories":"Food and Beverages,Fast Food","category_array":{"Food and Beverages":["Fast Food"]},"featured":"No","publisher_exclusive":"N","url":"https:\/\/box8.in\/offers","smartLink":"https:\/\/smartlink.linkmydeals.com\/?account_id=18950&network=&url=https%3A%2F%2Fbox8.in%2Foffers","image_url":"","type":"Deal","offer":"Freebie","status":"new","start_date":"2023-01-11","end_date":"2023-06-27"}]}

What I want is value inside offers key, and map it to a class called Offers that looks like this:

data class Offers (
    val lmd_id: Int,
    val store: String?,
    val merchant_homepage: String?,
    val long_offer: String?,
    val title: String?,
    val description: String?,
    val code: String?,
    val terms_and_conditions: String?,
    val categories: String?,
    val featured: String?,
    val publisher_exclusive: String?,
    val url: String?,
    val smartlink: String?,
    val image_url: String?,
    val type: String?,
    val offer: String?,
    val offer_value: String?,
    val status: String?,
    val start_date: String?,
    val end_date: String?
)

But it doesn't seem there is a way to do that and the key called result is creating a problem.

I created an object,

object DealsNetwork {
    fun getRetrofitClient (): Retrofit {
        val gson = GsonBuilder ().setLenient ().create ()
        return Retrofit.Builder ()
            .baseUrl ("https://feed.linkmydeals.com/")
            .addConverterFactory (GsonConverterFactory.create (gson))
            .build ()
    }
}

A service,

interface DealsService {
    @GET("getOffers/?API_KEY=$api_key&incremental=1&format=json")
    suspend fun getOffers (): List<Offers>
}

And finally I called it in my Fragment,

        val dealsService = DealsNetwork.getRetrofitClient ().create (DealsService::class.java)


        CoroutineScope (Dispatchers.IO).launch {
            // Get list of offers
            val offers = dealsService.getOffers ()

            // Do something with the results on the main thread
            withContext (Dispatchers.Main) {
                val rvDealsAdapter = DealsListRecyclerAdapter(deals, dealsViewModel)

                binding.rvDealsList.layoutManager = layoutManager
                binding.rvDealsList.adapter = rvDealsAdapter
            }

But this doesn't seem to work, any help is highly appreciated.


Solution

  • You must create a data class that matches your API response. From your response, I can see that it's a JSON object containing the list you want to extract. You should create your Response data class as follows:

    data class Response(
        result: Boolean,
        offers: List<Offers>
    )
    

    Here, the result variable is optional. Then use this Response data class in your Retrofit API:

    interface DealsService {
        @GET("getOffers/?API_KEY=$api_key&incremental=1&format=json")
        suspend fun getOffers (): Response
    }
    

    Hope it helps!