David Luque
David Luque

Reputation: 1108

Retrofit returns null values

I am using Retrofit and I am a quite noob in Android.

My JSON response

    {
    "movie": {
        "_id": "568661682d33bca267fdf81b",
        "poster_path": "https://image.tmdb.org/t/p/w154/xHfhQIK4BNlsGv5Ylx8mVq0hJT1.jpg",
        "adult": false,
        "overview": "",
        "release_date": "2015-05-15",
        "id": 76341,
        "original_title": "Mad Max: Fury Road",
        "original_language": "en",
        "title": "Mad Max: Furia en la carretera",
        "vote_count": 3105,
        "__v": 0,
        "popular": true,
        "production_companies": [],
        "cast": [],
        "genre_ids": [
            53,
            28,
            12
        ]
    }
}

This is my Movie model:

public class Movie {

public String Id;
//more variables

public String getId() {
    return Id;
}

public void setId(String id) {
    Id = id;
}
//more getter and setter

My Retrofit interface

public interface MyApiEndPointsInterface {
  @GET("/movie/{id}")
  Call<Movie> getMovie(@Path("id") int id);
}

And the code in the activity

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

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

    Call<Movie> call = apiService.getMovie(76341);

    call.enqueue(new Callback<Movie>() {
        @Override
        public void onResponse(Response<Movie> response, Retrofit retrofit) {
            Log.d("MainActivity", response.body().title);
        }

        @Override
        public void onFailure(Throwable t) {

        }
    });

I thinks it can be the JSON response because it has an superior instance, but I don't know how to work with it in the code.

I don't get an response, is it all correct?

Upvotes: 3

Views: 8291

Answers (3)

GreyBeardedGeek
GreyBeardedGeek

Reputation: 30088

The problem is that the JSON parser is not expecting the un-named root object that is wrapping the 'movie' data in the JSON.

If you can change the JSON that the server returns, remove the outer object so that you have just

{
    "_id": "568661682d33bca267fdf81b",
    "poster_path": "https://image.tmdb.org/t/p/w154/xHfhQIK4BNlsGv5Ylx8mVq0hJT1.jpg",
    "adult": false,
    "overview": "",
    "release_date": "2015-05-15",
    "id": 76341,
    "original_title": "Mad Max: Fury Road",
    "original_language": "en",
    "title": "Mad Max: Furia en la carretera",
    "vote_count": 3105,
    "__v": 0,
    "popular": true,
    "production_companies": [],
    "cast": [],
    "genre_ids": [
        53,
        28,
        12
    ]
}

If you can't alter the server's response, there's a few ways to handle it on the client side. I'd simply create another object to map to the outer JSON object, so leaving your existing Movie class as-is, add:

public class MovieResponse {
 public Movie movie;
}

and then change the Retrofit call to use the MovieResponse instead of the Movie. You can then refer to

movieResponse.movie

Upvotes: 5

Joopkins
Joopkins

Reputation: 1644

Your String names are case sensitive to how they appear in the JSON output. Change String Id to String id and it should work, it doesn't matter in the getter and setter names (getId works for instance), but the variable itself needs to match the case in the JSON.

Upvotes: 2

SemaphoreMetaphor
SemaphoreMetaphor

Reputation: 691

Change movie model to:

public class Movie { 

    @SerializedName("_id")
    public String id;
    //more variables 

    public String getId() {
        return Id;
    } 

    public void setId(String id) {
        id = id;
    }
}

Gson needs to know exactly how to map your model via reflection. It mainly uses your variable name if you dont state otherwise.

Upvotes: 1

Related Questions