I have an app which is querying an endpoint and then simply placing the response in a ListView. However, the 'onFailure' is returning the message 'Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $'.
I have looked at similar questions but cannot seem to figure it out in the context of my app.
In the OnCreate I've setup the base URL for the endpoint then added my API key on and a call is made to an interface which Queries the necessary parameters:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
myLocationButton = findViewById(R.id.myLocationBtn);
myLocationButton.setOnClickListener(this);
eventList = findViewById(R.id.evenListView);
SearchView searchView = findViewById(R.id.searchView);
searchView.setIconified(false);
searchView.clearFocus();
String API_BASE_URL = "https://app.ticketmaster.com/discovery/v2/";
final String API_KEY = "HIDDEN";
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl originalHttpUrl = original.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter("apikey", API_KEY)
.build();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder().url(url);
Request request = requestBuilder.build();
return chain.proceed(request);
}
}).build();
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(
GsonConverterFactory.create()
);
Retrofit retrofit = builder.client(httpClient).build();
ITicketMasterAPI event = retrofit.create(ITicketMasterAPI.class);
Call<List<TicketMasterEvent>> call = event.getLocalEvents("manchester",
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
call.enqueue(new Callback<List<TicketMasterEvent>>() {
@Override
public void onResponse(Call<List<TicketMasterEvent>> call, Response<List<TicketMasterEvent>> response) {
List<TicketMasterEvent> events = response.body();
eventList.setAdapter(new TMEventAdapter(SearchActivity.this, events));
Toast.makeText(SearchActivity.this,"something happened", Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(Call<List<TicketMasterEvent>> call, Throwable t) {
RequestBody test = call.request().body();
Toast.makeText(SearchActivity.this, "didn't work", Toast.LENGTH_LONG).show();
}
});
}
Here's the interface with the queries:
public interface ITicketMasterAPI {
@GET("events.json")
Call <List<TicketMasterEvent>> getLocalEvents(
@Query("city") String city,
@Query("id") String id,
@Query("keyword") String keyword,
@Query("attractionId") String attractionId,
@Query("venueId") String venueId,
@Query("postalCode") String postalCode,
@Query("latlong") String latlong,
@Query("radius") String radius,
@Query("unit") String unit,
@Query("source") String source,
@Query("locale") String locale,
@Query("marketId") String marketId,
@Query("startDateTime") String startDateTime,
@Query("endDateTime") String endDateTime,
@Query("includeTBA") String includeTBA,
@Query("includeTBD") String includeTBD,
@Query("includeTest") String includeTest,
@Query("size") String size,
@Query("page") String page,
@Query("sort") String sort,
@Query("onsaleStartDateTime") String onsaleStartDateTime,
@Query("onsaleEndDateTime") String onsaleEndDateTime,
@Query("countryCode") String countryCode,
@Query("stateCode") String stateCode,
@Query("stateCode") String classificationName,
@Query("classificationId") String classificationId,
@Query("dmaId") String dmaId,
@Query("segmentId") String segmentId,
@Query("segmentName") String segmentName,
@Query("promoterId") String promoterId,
@Query("clientVisibility") String clientVisibility,
@Query("geoPoint") String geoPoint,
@Query("includeLicensedContent") String includeLicensedContent,
@Query("includeSpellcheck") String includeSpellcheck);
}
And the model for the data. At the moment I am only wanting the name:
public class TicketMasterEvent {
public String eventName;
public String getEventName() {
return eventName;
}
UPDATE
I've not changed all the Lists to be of just type 'TicketMasterEvent' which causes it to return a status code of "200 - OK". However, as suggested, I looked at the actual response in Postman and this is what I got:
UPDATE 2
I made the following changes...
public class TicketMasterEvent {
@SerializedName("_embedded")
EventEmbedded embedded;
public String getName() {
return name;
}
@SerializedName("name")
@Expose
private String name;
@SerializedName("type")
@Expose
private String type;
@SerializedName("id")
@Expose
private int id;
@SerializedName("test")
@Expose
private String test;
@SerializedName("url")
@Expose
private String url;
@SerializedName("locale")
@Expose
private String locale;
@SerializedName("images")
@Expose
private List<EventImages> images;
}
public class EventEmbedded {
@SerializedName("events")
@Expose
List<TicketMasterEvent> events;
}
UPDATE 3 - it works!
Ok, so here's the response I got:
This only seems to work when the call made is of type TicketMasterEvent and not a list - that's the same in the interface too. However, I have noticed in the body that it has some null properties - is that a problem?
And also, by not having it return as a list I can't get it to populate my list view - any ideas on that?