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
Hit
s with aRecipe
- 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
Return a Value from Asynctask in Android
Error: Unable to Run Mksdcard Sdk Tool
How to Execute Linux Commands on a Remote MAChine Using Java
Expected Begin_Array But Was Begin_Object at Line 1 Column 2
Java.Io.Console Support in Eclipse Ide
Comparing Two Integer Arrays in Java
Generate a Random Double in a Range
Getoutputstream() Has Already Been Called for This Response
Test If Element Is Present Using Selenium Webdriver
How to Load a Resource from Web-Inf Directory of a Web Archive
Transitive Dependencies Not Resolved for Aar Library Using Gradle
Android Reading from an Input Stream Efficiently
Can't Make Jdbc Connection to MySQL (Using Java, Intellij, and Linux)
What Is the Purpose of Java's Unary Plus Operator
How to Call a Stored Procedure from Java and JPA
Date and Time Conversion to Some Other Timezone in Java
How to Read System Environment Variable in Spring Applicationcontext