Search code examples
javaandroidapikotlinretrofit2

how to display categories in data class with retrofit2 - Kotlin


i am trying to display data from API using retrofit2 in koltin

but the API shows that there is categoryId before the data i am calling as showing below:

  [
   {
    "categoryId": 0,
    "categoryName": "string",
    "ilmFinders": [
    {
    "eventId": 0,
    "eventName": "string",
    "eventLocation": "string",
    "eventPhoto": {},
    "eventDescription": "string",
    "eventDate": "string",
    "eventLink": "string",
    "isFavourite": {}
    }
    ]
   }
  ]

i tried to call only (eventName, eventPhoto, eventLink) in my data class as showing below:

data class IimfinderData(

val eventLink: String,
val eventPhoto: String,
val eventName: String

)

API interface:

        interface finderService {
        @GET(" ")
        fun getServices() : Call<List<IimfinderData>>
        companion object Factory {
        fun create(): finderService {
        val retrofit = Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("PRIVATE URL")
            .build()

        return retrofit.create(finderService::class.java)
        }
        }
        }

Adapter:

class IimfinderAdapter(var countryList: List<IimfinderData>, var activity: MainActivity): RecyclerView.Adapter<IimfinderAdapter.ViewHolder>(){
lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IimfinderAdapter.ViewHolder {
    context = parent.context!!
    val view = LayoutInflater.from(context).inflate(R.layout.list_item2, parent, false)
    return ViewHolder(view)
}

override fun getItemCount(): Int {
    return countryList.size
}

override fun onBindViewHolder(holder: IimfinderAdapter.ViewHolder, position: Int) {
    holder.eventName.text = countryList[position].eventName
    holder.eventLink.text = countryList[position].eventLink




    Picasso.with(activity)
        .load(countryList[position].eventPhoto)
        .error(R.drawable.qiblacompass)
        .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
        .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
        .into(holder.eventPhoto)




}

class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    val eventName: TextView = itemView.findViewById(R.id.title_tv2)
    val eventLink: TextView = itemView.findViewById(R.id.tv_url2)
    val eventPhoto: ImageView = itemView.findViewById(R.id.thumbnail_tv2)

}

}

after i run the application, it shows that the data are null

do i need to call "categoryId"?

and if yes, how can i call 2 arrays in the same data class?

the Adapter and the code in my activity is correct because i tested it with another API

so what am i doing wrong here?

------------------------------- Solution ------------------------

refer to the answer down and i have to change how i call the data from the adapter

instead of this:

holder.eventName.text = countryList[position].eventName

do this:

holder.eventName.text = countryList[position].ilmFinders[position].eventName

Solution

  • Check point

    • data that you want is in List of List
      • jsonArray > jsonArray > IimfinderDataJson IimfinderData by List
    • eventPhoto is Object, not String

    try this code

    Call<List<IimfinderData>> -> Call<List<IlmFinders>>

    fun getServices() : Call<List<IlmFinders>>
    

    and

    data class IlmFinders(
        @SerializedName("ilmFinders")
        val ilmFinders: List<IimfinderData>
    )
    
    data class IimfinderData(
        @SerializedName("eventLink")
        val eventLink: String,
        @SerializedName("eventPhoto")
        val eventPhoto: Any,
        @SerializedName("eventName")
        val eventName: String
    )
    

    if your data class properties name is same with json element, you don't need @SerializedName