Miller Mosquera
Miller Mosquera

Reputation: 119

Null Object In Retrofit2

Everybody.

I'm attempting to connect to a RestApi with retrofit2, but this ever give me error or return object null.

{"news": [ {  "News": {   "id": "1",  "title": "Big data is changing the ace f fashion", "description": "Download Fashioning Data: A 2015 Update"  } }]}

I have the next code:

Interface rest

@GET("news")
Call<news> getNews();

POJO object:

public class news {

@SerializedName("News")
public List<Listnews> listnews;

public static class Listnews{

    public News news;

    public static class News{

        @SerializedName("id")
        private String id;

        @SerializedName("title")
        private String title;

        @SerializedName("description")
        private String description;

        // getters and setters
    }

}

And show in the mainActivity

 Call<news> call2 = api.getNews();

    call2.enqueue(new Callback<news>() {

        @Override
        public void onResponse(Call<news> call, Response<news> response) {

            if (response.code() == 200){

                List<news.Listnews> respuesta =  response.body().listnews;

                System.out.println( "title: "+ respuesta.get(0).news);


            }

        }

        @Override
        public void onFailure( Call<news> call, Throwable t ) {

            System.out.println( t + " Error " );

        }

    });

But this ever return null.

Upvotes: 0

Views: 729

Answers (3)

Rushi M Thakker
Rushi M Thakker

Reputation: 679

This worked for me. I don't know why you have taken static class. I have done it simply like this:

POJO class News.java:

public class News
{
String id, title, description;

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;
}

public String getDescription()
{
    return description;
}

public void setDescription(String description)
{
    this.description = description;
}
}

API Interface:

public interface NewsAPI
{
    @POST("/loltry.php")
    Call<NewsList> getNews();
}

NewsList.java:

public class NewsList
{
    @SerializedName("news")
    ArrayList<Data> d;
}

Data.java:

public class Data
{
    @SerializedName("data")
    News n;
}

NewsList newsList = response.body();

String rootUrl = "http://192.168.0.5"; 
Retrofit adapter = new Retrofit.Builder().baseUrl(rootUrl).addConverterFactory(GsonConverterFactory.create()).build();
NewsAPI newsAPI = adapter.create(NewsAPI.class);
final Call<NewsList> call = newsAPI.getNews();
call.enqueue(new Callback<NewsList>()
{
    @Override
                public void onResponse(Call<NewsList> call, Response<NewsList> response)
                {
                    Toast.makeText(MainActivity.this, "Succcessss", Toast.LENGTH_LONG).show();
                    newsList = response.body();
                   try
                    {
                        for (int i = 0; i < newsList.d.size(); ++i)
                        {
                              newsListArray.add(i, newsList.d.get(i).n.getTitle());
                        }
                    } catch (Exception e)
                    {
                          e.printStackTrace();
                    }
                }

Here loltry.php on my localhost is sending json object that you are trying to parse. And I am displaying the title in your "News"(my "data") object in a listview.

This is my JSONResponse:

{"news":[{"data":{"id":"1","title":"Big data is changing the ace f fashion","description":"Download Fashioning Data: A 2015 Update"}}]}

Upvotes: 0

Code_Life
Code_Life

Reputation: 5892

Please do the following changes in your class , hopefully this should work. Let me know if it doesn't.

public class news {

// Change 1 --- 
@SerializedName("news")
public List<Listnews> listnews;

public static class Listnews{

// Change 2 --- 
@SerializedName("News")
public News news;

public static class News{

    @SerializedName("id")
    private String id;

    @SerializedName("title")
    private String title;

    @SerializedName("description")
    private String description;

    // getters and setters
} }

Upvotes: 2

Long Ranger
Long Ranger

Reputation: 6008

You have two "news", "News" inside your json string.

Since your model annotated with the following

News(array)

-> id

-> title

-> description

{
    "News": [
        { "id": "1", "title": "Big data is changing the ace f fashion", "description": "Download Fashioning Data: A 2015 Update" },
        { "id": "2", "title": "Big data is changing the ace f fashion", "description": "Download Fashioning Data: A 2015 Update" }
    ]
}

But in your json string

{
    "news": [{
        "News": { "id": "1", "title": "Big data is changing the ace f fashion", "description": "Download Fashioning Data: A 2015 Update" }
    }]
}

You can see the structure:

news(array)

->News(objects)

->id

->title

->description

Therefore, you cannot phase any data inside it.

The above is the reason you get null object, and you should use the first json structure to get the news data

The following is the suggestion for your work

  1. Dont confused with the words "news" and the data structures "News" (http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) It is okay for you to use "news" as the path to get the list of the news. But it will be painful if you have another "News" or "Listnews" in the return json since it is quite confused to findout which one should be the news. Try another word like "data", "items" or just return an arraylist of the news since your path (http://restful.com/news) notified you are trying to fetch the list of news

  2. Build test case for your restful. It will be painful if you tried to test every restful api in you mobile application. Try to use the following

    A. Build the instrument test (https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html) for you to demo the button click to trigger the restful

    B. Mock the request using retrofit(https://github.com/square/okhttp/tree/master/mockwebserver) and copy your json string into the escaped character one(using this website http://bernhardhaeussner.de/odd/json-escape/)

These two ways will save a lot of your time in the development

Upvotes: 0

Related Questions