Solution 1 :
I came up with something that worked, but I don’t think it is ideal.
Rather than use the GsonConverter that is inbuild to retrofit, I do it myself.
inside onResponse I do the following
val peopleList = GsonBuilder()
.create()
.fromJson(response.body()!!.getAsJsonArray("people"), Array<Person>::class.java).toList()
Log.d("First person", peopleList!![0])
I am not at all sure this is better then just having extra data classes though
Problem :
I have working code that allows me parse the Json files I get from a retrofit API get call. However, the way I am currently doing it requires two classes (one of which is just a list containing the other), and if I was wondering if it is possible to do this with a single data class. More explanation is below.
What I have:
Interface:
interface ApiInterface {
@GET(value = "all_people.php")
fun getAllPeople(): Call<People>
}
Code:
retrofit: ApiInterface = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
.create(ApiInterface::class.java)
retrofit.getAllPeople().enqueue(object : Callback<People?> {
override fun onResponse(call: Call<People?>, response: Response<People?>) {
Log.d("First person", responce.body()!!.people[0])
}
override fun onFailure(call: Call<People?>, t: Throwable) {}
})
Data classes:
data class Person (
val firstName: String,
val lastName: String
)
data class People (
val people: List<Person>
)
THIS IS WORKING
The issue is that this requires an additional class (People). This is because I am getting back from the API a JSON object (Which contains the JSON array I want to access). This is the solution I have found online when I look at scenarios like this, however, this method requires me to create an additional class, containing just a list, for every different API call I have. Which is obviously not ideal.
Question: My question is how would I do this while eliminating the class People?
I want to do something like this:
Interface:
interface ApiInterface {
@GET(value = "all_people.php")
fun getAllPeople(): Call<List<Person>>
}
Code:
retrofit: ApiInterface = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
.create(ApiInterface::class.java)
retrofit.getAllPeople().enqueue(object : Callback<List<Person>?> {
override fun onResponse(call: Call<List<Person>?>, response: Response<List<Person>?>) {
//The issue is here, because this is a Json object, and I am treating it like a list
//Is there a way of access the Json array inside this Json object without creating the person class?
Log.d("First person", responce.body()!![0])
}
override fun onFailure(call: Call<List<Person>?>, t: Throwable) {}
})
However, I can’t figure out how to “open” the Json obect to get this to work and therefore get this error code:
Comments
Comment posted by Campino
responce.body() must be a object type List
Comment posted by Campino
if response.body is not already a List