Retrofit request returning null for specific data model

359
February 16, 2017, at 00:51 AM

I am trying to make an API request to the Imgur API that should return the following data model:

"data": [{
        "id": "CiDkx",
        "title": "Did You Know",
        [...]                     
    } [...]
    ],
"success": true,
"status": 200
}

But I am failing to understand how to achieve it.

So far here is how I try to do it:

public interface ImgurAPI {
    @GET("gallery/hot/viral/{page}")
    Call<ImageData> getGallery(@Path("page") String page); 
}
static final String BASE_URL = "https://api.imgur.com/3/";
public void start() {
    Gson gson = new GsonBuilder()
            .setLenient()
            .create();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();
    ImgurAPI githubAPI = retrofit.create(ImgurAPI.class);
    Call<ImageData> call = githubAPI.getGallery("0");
    call.enqueue(this);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onResponse(Call<ImageData> call, Response<ImageData> response) {
    if(response.isSuccessful()) {
        ImageData image = response.body();
    } else {
        System.out.println(response.errorBody());
    }
}

Where ImageData is a container class like such:

public class ImageData {
    public String id;
    public String title;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}

The request does go through but the response I receive has an id and a title that are null.

I am almost certain that I have not understood how to organize my model (or should I say container?) classes, am I right in that sense?

Answer 1

You're very close on this, I'd recommend debugging or adding some Retrofit logging to figure it out.

Without seeing further info it looks like your ImageData class doesn't match the JSON you're using. Take a look at https://api.imgur.com/3/gallery/hot/viral/0.json ...

{
"data": [{
    "id": "CiDkx",
    "title": "Did You Know",
    "description": null,
    "datetime": 1487140997,
    "cover": "yZXOBMq",
    ...
}]

}

That STARTS with an OBJECT that is unnamed which holds an ARRAY named "data" and that holds further OBJECTS with each image's info, like ID and title and such that you're using.

Your ImageData class is just one of the image data items, it's not the collection that Retrofit and GSON are getting and trying to parse. You need a class for the collection, or further annotations. Try something like this...

    public class ImageDataCollection {
       @SerializedName("data")
       private List<ImageData> imageDataList;
       public List<ImageData> getImageDataList() {
          return imageDataList;
       }
       public void setImageDataList(List<ImageData> imageDataList) {
          this.imageDataList = imageDataList;
       }  
    }

And then have your ImgUr interface handle that collection wrapper, instead of a single ImageData object. (And note that you can add the success and status fields and such to the outer collection/wrapper too, if you want to check that, which would probably be a good idea.)

READ ALSO
Timepicker UI looks different on the same Android version

Timepicker UI looks different on the same Android version

I'm developing an Ionic 2 application with use of DatePicker Plugin for Cordova suggested by Ionic documentation

302
Multi-Level ExpandedListView from JSON

Multi-Level ExpandedListView from JSON

I have such Json Array, trying do custom adapter but have problems with writing viewingSome body can help?

280
How to display google maps in 2D view?

How to display google maps in 2D view?

I have created a custom map styling following this tutorial

516
How can I increase the timeout in Download Manager?

How can I increase the timeout in Download Manager?

I have a functionality in my file/directory browsing app where the user can download the current directory they are inThis works for a folder with a moderate size (<100 MB) so zipping doesn't take much time on the server side, but then when the size of the folder...

381