1

Hey guys I'm trying to get data from an API. I can use this https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json json file it's work but I can't make this work. https://www.episodate.com/api/most-popular?page=1

HERE IS MY MAIN ACTIVITY

private fun loadData(){

    val retrofit = Retrofit.Builder()
            .baseUrl("https://www.episodate.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MovieAPI::class.java)

    CoroutineScope(Dispatchers.IO).launch {
        val response = retrofit.getData()

        if (response.isSuccessful){
            response.body()?.let {
                Moviemodel = ArrayList(it)
            }
        }
        println(Moviemodel)

    }

MY DATACLASS

data class MovieModel(
    val name: String
)

AND API CLASS

interface MovieAPI {
@GET("api/most-popular?page=1")
suspend fun getData(): Response<ArrayList<MovieModel>>

When I try https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json this file I can get datas but whenever I try this https://www.episodate.com/api/most-popular?page=1 apps crash. Please take a look thank you.

dltayn
  • 51
  • 2
  • 9
  • You can't use the same model class for different response bodies, generate another model class for the second API. – Sreehari K May 15 '21 at 07:48
  • I did it. I tried kotlin dataclass file from json plugin as well and I also tried with another json files this data class worked. But some json files cause the crash. I couldn't find it – dltayn May 15 '21 at 07:56

3 Answers3

1

How to parse nested List with Retrofit and Gson? Here is a similar question. Your models should be like

data class Movie(
    val page: Int,
    val pages: Int,
    val total: String,
    val tv_shows: List<TvShow>
)
data class TvShow(
    val country: String,
    val end_date: Any,
    val id: Int,
    val image_thumbnail_path: String,
    val name: String,
    val network: String,
    val permalink: String,
    val start_date: String,
    val status: String
)

Then API class

interface MovieAPI {
@GET("api/most-popular?page=1")
suspend fun getData(): Response<Movie>//instead of Response<ArrayList<Movie>>

In the activity

 CoroutineScope(Dispatchers.IO).launch {
        val response = retrofit.getData()

        if (response.isSuccessful){
            response.body()?.let {
                shows = List(it.tv_shows)
            }
        }
       for(show in shows){
       println(show.name) // here are the names
       }
    }

If you want to use different property names for your models, you should annotate those property names with @SerializedName(). for more information please refer to Gson: @Expose vs @SerializedName

Jarnojr
  • 543
  • 1
  • 7
  • 18
  • it's worked but can I ask a question? Why we used Response instead of Response> – dltayn May 17 '21 at 13:44
  • @Tunahan As Sushant Hande has mentioned since your API response starts with curly braces "{}" it is a JSON object, not a JSON array. So it is not a list, it is a single object. Please check his answer again also check out [here](https://stackoverflow.com/questions/12289844/difference-between-jsonobject-and-jsonarray) – Jarnojr May 17 '21 at 15:15
0

First one is a json list but second one is a json object that includes list so you can't parse directly to list. You should have class that includes list object. For example:

data class MoviePageModel(
    val total: Int,
    val page: Int,
    val tvShows: List<MovieModel>
)
0
  1. https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json
    In case of response from this URL, if you see the response is wrapped with rectangular brackets that is "[]". This means the response would be in the JSON array.

  2. https://www.episodate.com/api/most-popular?page=1
    In case of response from this URL, if you see the response is wrapped with curly braces that is "{}". This means the response would be in the JSON object.

In the following line, you have mentioned that the response would be ArrayList of MovieModel but actually it would be a JSON array in the case of the first URL, and in the case of the second it would be a JSON object. suspend fun getData(): Response<ArrayList>

In order to solve this issue, you need to define the separate response model for each URL.

  • I can solve JSON array but I can't handle with JSON object I couldn't understand what I need. I'm creating a class that includes tvShows: List object but I don't know what I need to next. – dltayn May 15 '21 at 09:13