Reputation: 463
I want to fetch json from a url https://api.myjson.com/bins/mxcsl/ using retrofit and rxjava. Sample json is this :
{
"data": [
{
"itemId": "1",
"desc": "Batcave",
"audio": "https://storage.googleapis.com/a/17.mp3"
},
{
"itemId": "2",
"desc": "Fight Club rules",
"audio": "https://storage.googleapis.com/a/2514.mp3"
},
{
"itemId": "3",
"desc": "Make an offer",
"audio": "https://storage.googleapis.com/a/47.mp3"
}]}
And here is my code : Data Model :
public class Data {
private String itemId;
private String desc;
private String audio;
public String getItem() {
return itemId;
}
public String getDesc() {
return desc;
}
public String getAudio() {
return audio;
}}
This is the Interface :
public interface RequestInterface {
@GET("/bins/mxcsl/")
Observable<List<Data>> register();
}
I'm loading something like this :
private void loadJSON() {
RequestInterface requestInterface = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(RequestInterface.class);
mCompositeDisposable.add(requestInterface.register()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleResponse,this::handleError));
}
private void handleResponse(List<Data> androidList) {
mAndroidArrayList = new ArrayList<>(androidList);
mAdapter = new DataAdapter(mAndroidArrayList);
mRecyclerView.setAdapter(mAdapter);
}
private void handleError(Throwable error) {
Toast.makeText(this, "Error "+error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
But Also I'm getting the error expected BEGIN_ARRAY but was BEGIN_OBJECT
I don't know where this is going wrong. Please help.
Upvotes: 0
Views: 1478
Reputation: 6142
Your api response is a JSONObject
which contain a JSONArray
with key data
.
Wrap your List of Data with another Model class
public class ResponseData {
@SerializedName("data")
private List<Data> dataList;
public List<Data> getDataList() {
return dataList;
}
public void setDataList(List<Data> list) {
dataList = list;
}
}
Use ResponseData
class in RequestInterface
public interface RequestInterface {
@GET("/bins/mxcsl/")
Observable<ResponseData> register();
}
Added:
As your converted Response is ResponseData
object so your handleResponse
method parameter would be ResponseData
type. In handleResponse
get your expected list from getter method and set it to Adapter
.
handleResponse
method
private void handleResponse(ResponseData responseData) {
if( responseData != null){
List<Data> dataList = responseData.getDataList();
mAndroidArrayList = new ArrayList<>();
if(dataList!= null){
mAndroidArrayList.addAll(dataList);
}
mAdapter = new DataAdapter(mAndroidArrayList);
mRecyclerView.setAdapter(mAdapter);
}
}
Upvotes: 2
Reputation: 3389
The error is because Retrofit is expecting a json array to be deserialized as a List
public interface RequestInterface {
@GET("/bins/mxcsl/")
Observable<List<Data>> register();
}
But the json response is an object with a field named data that is an array
{
"data": [
{
"itemId": "1",
"desc": "Batcave",
"audio": "https://storage.googleapis.com/a/17.mp3"
},
{
"itemId": "2",
"desc": "Fight Club rules",
"audio": "https://storage.googleapis.com/a/2514.mp3"
},
{
"itemId": "3",
"desc": "Make an offer",
"audio": "https://storage.googleapis.com/a/47.mp3"
}]}
Upvotes: 0
Reputation: 13057
Your type
Observable<List<Data>> register();
is wrong. Because Json's first level is not Array (But object with field data
, that is array).
You should create class for outer structure
public class Outer{
List<Data> data;
}
And specify in retrofit, as observable:
@GET("/bins/mxcsl/")
Observable<Outer> register();
Upvotes: 3