leolion3
leolion3

Reputation: 15

Expected BEGIN_ARRAY but was BEGIN_OBJECT with Retrofit

So I am trying to load data from the corona api.

This is my interface:

public interface RKIApi {

String BASE_URL = "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/";

@Headers("Content-Type: application/json")
@GET("query?where=1%3D1&outFields=cases,deaths,cases_per_population,county,death_rate&returnGeometry=false&outSR=4326&f=json")
Call<List<County>> getCounties();
}

This is my county data class to which I wish to convert the data I receive:

public class County {

@SerializedName("county")
@Expose
private String county;

@SerializedName("cases")
@Expose
private int cases;

@SerializedName("deaths")
@Expose
private int deaths;

@SerializedName("cases_per_population")
@Expose
private float casesPerPopulation;

@SerializedName("death_rate")
@Expose
private float deathRate;

public County(String county, int cases, int deaths, float casesPerPopulation, float deathRate) {
    this.county = county;
    this.cases = cases;
    this.deaths = deaths;
    this.casesPerPopulation = casesPerPopulation;
    this.deathRate = deathRate;
}

... Getters and Setters....

And this is how I am trying to load the data:

Retrofit retrofit = new Retrofit.Builder().baseUrl(RKIApi.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

    RKIApi apiService = retrofit.create(RKIApi.class);

    Call<List<County>> call = apiService.getCounties();

    call.enqueue(new Callback<List<County>>() {
        @Override
        public void onResponse(@NonNull Call<List<County>> call,@NonNull Response<List<County>> response) {
            ... Do something ...
        }

        @Override
        public void onFailure(@NonNull Call<List<County>> call,@NonNull Throwable t) {
            System.out.println("========== ERROR ==========");
            System.out.println(t.getMessage());
        }
    });

However when I try to open the app with the debugger enabled all I get is Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $. Now this is obviously because the JSON doesn't start with the list of counties, I would however only like to load them. I have tried using the Expose Tag as seen above however its still not working.

Any help is very much appreciated :)

Upvotes: 0

Views: 159

Answers (2)

Claudio Ferraro
Claudio Ferraro

Reputation: 4721

The problem and reason of the error is either in a bad designed API or in an misinterpreted api. Your api is not sending a List of objects. Most probably the API is spitting a JSON like this:

 { ...content }

Which is not a list of objects but a Single object. Retrofit is expecting something like this:

 [ { ....County } { ..County  }? ]

because You told to retrofit to return a LIST of List<County>.

Where the [ means an array of Objects. So in order to fix this You have 2 choices. Either change the api so it will return always the square brackets even for empty List like this [] or this [{ one object }] for a single result.

Either parse Your results manually. Check please this question here on stackoverflow:

Manually parse part of a response when using Retrofit

Upvotes: 0

pavel
pavel

Reputation: 1681

This means any of your parameter getting null or don't have anything in the json. Suppose you parse "name"= "pavel" but in the json that is "name"=null

Upvotes: 1

Related Questions