Retrofit2 Android: Expected Begin_Array But Was Begin_Object at Line 1 Column 2 Path $

Retrofit2 Android: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

When you say "This code is working with this payload:... but not with this one:..." that's expected and that's how it's suppose to work. In fact the error message tells you that while converting the json to a java object the call expected an array in the json but got an object instead.

This call:

@GET("Music")
Call<List<Music>> getMusicList();

expects a list of Music objects, that's why it works with the json:

[
{
"login": "JakeWharton",
...
},
...
]

Because the json itself is an array of your Music objects (Retrofit can convert between json arrays to java lists). For the second json you have just an object and not an array (notice the lack of [...]). For this you need to create another call with another model that maps to that json. Let's assume you've named the model MusicList. Here's how the call could look like:

@GET("Music")
Call<MusicList> getMusicList();

(Note that you might need to change the method name if you want to keep both the first call and this one).

The MusicList model can look something like this:

public class MusicList {
@SerializedName("data")
private List<Music> musics;
// ...
}

I'm assuming that the data array is a list of Music objects, but I did notice that the jsons are completely different. You might need to adapt this as well, but I think you get the picture here.

Error in Kotlin (Retrofit) Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ [SOLVED]

In your Retrofit service, you're saying you expect a List of items to come back, but your API is returning a single object with a list inside of it.

What you want to do instead is create a type called UserResults (or something similar) that contains a results property, which is a List<UsersItem>.

data class UserResults(
val results: List<UsersItem>
)

Then, your Retrofit function can return this new type instead:

@GET("api/users")
fun getUsers(): Call<UserResults>

expected begin_array but was begin_object at line 1 column 2 path $ retrofit

expected begin_array but was begin_object at line 1 column 2 path $ retrofit - this error means that GSON was expecting an array to come back from your server. We know this because your return type in Retrofit is Call<List<Score>>. Because you are expecting a list, GSON attempts to decode your response as a JSON array. The error goes on to state that while expecting an array, the first json token it encountered was the begin_object token. Have you used a proxy or just inspected the raw payload in response.body? My guess is that your response has an enclosing json object around the array, or it is only sending back a single Score object.

RETROFIT Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ KOTLIN

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

Retrofit Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ in onActivityResult

Your error tells you that it tries to make a list of something that can't be a list.
After some looking at the json I did found something that others haven't found yet.

The structure of the json is not starting as a list but as an object:

{
"q": "Sandwich",
"from": 0,
"to": 1,
"more": true,
"count": 16247,
"hits": [
// recipe is in here
]
}

This means that the Object that retrofit should be expecting is not of a type List<Recipe> but it should be an object of type RecipeResponse (defined below)

data class RecipeResponse(
@SerializedName("count")
val count: Int = 0,
@SerializedName("from")
val from: Int = 0,
@SerializedName("hits")
val hits: List<Hit>,
@SerializedName("more")
val more: Boolean = false,
@SerializedName("q")
val q: String = "",
@SerializedName("to")
val to: Int = 0
)

data class Hit(
@SerializedName("bookmarked")
val bookmarked: Boolean = false,
@SerializedName("bought")
val bought: Boolean = false,
@SerializedName("recipe")
val recipe: Recipe
)

In Hit you can use your recipe object

Don't forget to change the method in the interface to

@GET("search")
fun searchRecipe(
@Query("q") query: String,
@Query("app_id") app_id: String,
@Query("app_key") app_key: String,
@Query("from") from: Int,
@Query("to") to: Int
): Call<RecipeResponse>

Some things to note:

  • The list of recipes is now a list of Hits with a Recipe
  • The fields that are in RecipeResponse are not necessarily needed (depending of how you have GSON configured with Retrofit). The hits field is neccesary

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 retrofit2

JSON provided above contains only a single CharacterDTO object, but you expected to get a list of such objects. Either change the backend to return a list or replace getCharacters() declaration with:

suspend fun getCharacters(): CharacterDTO

retrofit E/API: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Your callback is looking for list from API Response, as you used this; Callback<List<Kanji>.

First Observe your API Response, It is {} JsonObject, and you casted it into List in your API Callback.

So fix this in your API Call like this;

  call.enqueue(object : Callback<Kanji>{
override fun onResponse(call: Call<Kanji>, response: Response<Kanji>) {
Log.i("API",response.body().toString())
}

override fun onFailure(call: Call<Kanji>, t: Throwable) {
t.message?.let { Log.e("API", it) }
}
})

also modify your Interface;

@GET("kanji/蛍")
fun getKanji(): Call<Kanji>


Related Topics



Leave a reply



Submit