Reputation: 2693
I am using retrofit to retrieve data from my server - it is a user search:
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<Movie>> call = apiService.getSearch(lng, 0, newText);
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {
movieList = response.body();
if (dialog != null) {
dialog.dismiss(); dialog = null;
}
if (response.isSuccessful()) {
recyclerAdapter.setMovieList(movieList);
} else {
showMsgSnack(getString(R.string.Nodata));
}
}
@Override
public void onFailure(@NonNull Call<List<Movie>> call, @NonNull Throwable t) {
if (dialog != null) {
dialog.dismiss(); dialog = null;
}
if(t instanceof UnknownHostException){
showMsgSnack(getString(R.string.Network));
}
else if(t instanceof SocketTimeoutException){
showMsgSnack(getString(R.string.ServerTimeout));
}
else {
showMsgSnack(getString(R.string.ServerError));
}
}
});
Json is generaed via PHP in the server. If the search is success, json will return like [{"title": "sometitle",...}].
But if there is no match in database, I am returning just an empty {}.
But in android it goes to the failure and shows ServerError message. I want to show in that case some message as No match found.
How can I handle this response?
I also created a Default callback for Nullpointerexception, but this still doesn't work:
call.enqueue(new DefaultCallback<>(new Callback<List<Movie>>() {
@Override
public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {
movieList = response.body();
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (response.isSuccessful()) {
recyclerAdapter.setMovieList(movieList);
} else {
showMsgSnack(getString(R.string.Nodata));
}
}
@Override
public void onFailure(@NonNull Call<List<Movie>> call, @NonNull Throwable t) {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (t instanceof UnknownHostException) {
showMsgSnack(getString(R.string.Network));
}
if (t instanceof NullPointerException) {
showMsgSnack(getString(R.string.Nodata));
} else if (t instanceof SocketTimeoutException) {
showMsgSnack(getString(R.string.ServerTimeout));
} else {
showMsgSnack(getString(R.string.ServerError));
}
}
}));
}
public static class DefaultCallback<T> implements Callback<T> {
private static final String TAG = "YOUR_TAG";
private final Callback<T> callback;
public DefaultCallback(Callback<T> callback) {
this.callback = callback;
}
@Override
public void onResponse(@NonNull Call<T> call, Response<T> response) {
if (response.body() == null) {
callback.onFailure(call, new NullPointerException("Empty response"));
} else {
callback.onResponse(call, response);
}
}
@Override
public void onFailure(@NonNull Call<T> call, Throwable t) {
Log.e(TAG, t.toString());
callback.onFailure(call, t);
}
}
It says: YOUR_TAG: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Upvotes: 0
Views: 198
Reputation: 91
In android after receiving response from API you want List of type Movie object (List) which is like [{"title": "sometitle",...}] this.
But when you don't find anything on search then you are returning " {} "
And here you are getting an issue, this is because you are excepting List means Array and API returning "{}" means Object.
Simple solution don't send object "{}" send Array "[]" and check
@Override
public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {
movieList = response.body();
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
if (movieList.size() > 0) {
recyclerAdapter.setMovieList(movieList);
} else {
showMsgSnack(getString(R.string.Nodata));
}
}
Hope you understand and this will help!
Upvotes: 1