data class Item(
val calories: Int,
val carbohydrates_total_g: Double,
val cholesterol_mg: Int,
val fat_saturated_g: Int,
val fat_total_g: Double,
val fiber_g: Double,
val name: String,
val potassium_mg: Int,
val protein_g: Double,
val serving_size_g: Int,
val sodium_mg: Int,
val sugar_g: Double
)
data class nutritionData(
val items: List<Item>
)
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request()
.newBuilder()
.addHeader("X-Api-Key", ApiHeaders.API_KEY)
.build()
chain.proceed(request)
}
.build()
interface NinjaAPI {
@GET("v1/nutrition?")
fun getNutrition(@Query("query") foodName: String): Call<List<nutritionData>>
}
const val BASE_URL = "https://api.calorieninjas.com/"
fun getMyNutrition(foodName: String) {
val retrofitBuilder = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(client)
.build()
.create(NinjaAPI::class.java)
val retrofitData = retrofitBuilder.getNutrition(foodName)
retrofitData.enqueue(object : Callback<List<nutritionData>?> {
override fun onResponse(
call: Call<List<nutritionData>?>,
response: Response<List<nutritionData>?>
) {
Log.d(TAG, "IT WORKED")
}
override fun onFailure(call: Call<List<nutritionData>?>, t: Throwable) {
Log.d(TAG, "onFailure: " + t.message)
}
})
}
I tried everything to display the (calories, fats, protein, and carbs) from CaloriesNinja API but I couldn't, I tried to check the catlog for info and turns out onRespons
e never occurred and all the button clicks go to onFailure
and produce:
onFailure: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
I Googled that and it is properly my formatting to the data from the API but I copied the response example they have and used the plugin to convert it to kotlin class.
You are specifying Call<List<nutritionData>>
as return type of the API call, that means the JSON data would have to look like this:
[
{
"items": [ ... ]
},
{
"items": [ ... ]
},
...
]
However, the JSON data is actually only a single JSON object which directly represents your nutritionData
:
{
"items": [ ... ]
}
Therefore you should change Call<List<nutritionData>>
to Call<nutritionData>
.
This is also what the Gson exception message is saying: You specified that the type is List<...>
so Gson expects a JSON array, but the JSON data actually starts with a JSON object. And the location information "line 1 column 2 path $" of the exception points you to that error location in the JSON data (possibly with some slight inaccuracies).