Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit response returning null in Android

I wanted to display a text from a JSON value. I'm using Retrofit to make API call I don't know if I'm doing it right. Anyway here's my code.

Here's the url link: http://api.icndb.com/jokes/random .

The website will display a random joke each time. Here's the example of an output from the website:

{ "type": "success", "value": { "id": 175, "joke": "When Chuck Norris was a baby, he didn't suck his mother's breast. His mother served him whiskey, straight out of the bottle.", "categories": [] } } 

fragment.java

    String url = "http://api.icndb.com/";

    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create());

    Retrofit retrofit = builder.build();

    RetroFitHelper client = retrofit.create(RetroFitHelper.class);
    Call<Api> call = client.findJoke("random");

    call.enqueue(new Callback<Api>() {
        @Override
        public void onResponse(Response<Api> response, Retrofit retrofit) {

            String result = response.body().getJoke();

            Toast.makeText(getContext()," The word is: " + result ,Toast.LENGTH_LONG).show();
        }

        @Override
        public void onFailure(Throwable t) {
            Toast.makeText(getContext()," Error..." ,Toast.LENGTH_LONG).show();

        }
    });

RetroFitHelper.java

public interface RetroFitHelper {

    @GET("/jokes/{random}")
    Call<Api> findJoke(@Path("random") String random);

}

Model class

public class Api {

    @SerializedName("joke")
    private String joke;

    public String getJoke() {
        return joke;
    }

    public void setJoke(String joke){
        this.joke = joke;
    }
}
like image 346
makkhay gurung Avatar asked Dec 23 '17 04:12

makkhay gurung


2 Answers

The provided json response has a json object named value inside another json object(It is of the form {..,"value":{}}). So we need two model classes - one for the outer json object and another one for the inner json object(value).

You will need to have two model classes like this

public class Api {

@SerializedName("type")
@Expose
private String type;
@SerializedName("value")
@Expose
private Value value;

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public Value getValue() {
return value;
}

public void setValue(Value value) {
this.value = value;
}

and the following one for value object

public class Value {

@SerializedName("id")
@Expose
private Integer id;
@SerializedName("joke")
@Expose
private String joke;
@SerializedName("categories")
@Expose
private List<Object> categories = null;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getJoke() {
return joke;
}

public void setJoke(String joke) {
this.joke = joke;
}

public List<Object> getCategories() {
return categories;
}

public void setCategories(List<Object> categories) {
this.categories = categories;
}

}

Now, response.body() will have the result of outer json object(Api) and response.body().getValue() will have the result for inner json object(Value) .

Now in your response callback, get response like this

String result = response.body().getValue().getJoke();

Also make sure that you have the necessary internet permission declared in your manifest like this

<uses-permission android:name="android.permission.INTERNET" />

Do ensure you have the latest dependencies setup in your app level build.gradle file

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

like image 193
Navneet Krishna Avatar answered Oct 17 '22 11:10

Navneet Krishna


As @Aswin suggest and @Navneet answered you have problem in your POJO class. I suggest you to use jsonschema2pojo or RoboPOJOGenerator so next time you avoid to stuck this kind of error.

Steps

1) Go to http://www.jsonschema2pojo.org/

2) Paste your response over there and enter package and class name

3) Choose target language as Java or Kotlin(if you are using)

4) Source type as Json

5) Annotation style as Gson

6) Click Preview

7) Copy and paste those classes to your app package

like image 5
Vishal G. Gohel Avatar answered Oct 17 '22 12:10

Vishal G. Gohel