Khashchuluun
Khashchuluun

Reputation: 169

How to make a model for comment?

Hello Web API gives me following JSON. It's for comment.

{
  "comment_count": 9,
  "comments": [
    {
      "comment_ID": "2",
      "comment_post_ID": "167",
      "comment_author": "admin",
      "comment_author_email": "[email protected]",
      "comment_author_url": "",
      "comment_author_IP": "::1",
      "comment_date": "2019-01-21 10:45:59",
      "comment_date_gmt": "2019-01-21 02:45:59",
      "comment_content": "asdada asda sda sd asdsada sd as",
      "comment_karma": "0",
      "comment_approved": "1",
      "comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
      "comment_type": "",
      "comment_parent": "0",
      "user_id": "1",
      "like_cnt": "1",
      "image": "",
      "author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
      "is_liked": true
    },
    {
      "comment_ID": "3",
      "comment_post_ID": "167",
      "comment_author": "admin",
      "comment_author_email": "[email protected]",
      "comment_author_url": "",
      "comment_author_IP": "::1",
      "comment_date": "2019-01-21 11:12:37",
      "comment_date_gmt": "2019-01-21 03:12:37",
      "comment_content": "a",
      "comment_karma": "0",
      "comment_approved": "1",
      "comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
      "comment_type": "",
      "comment_parent": "0",
      "user_id": "1",
      "like_cnt": "0",
      "image": "",
      "author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
      "is_liked": false
    }
  ]
}

Comment reply levels are unlimited. It can be many level. But I want to do it like facebook comment section. Which means:

A: comment - level 0
B: comment - level 0
   C: reply of comment B - level 1
      D: reply of comment C - level 2 

Comment D level is 2. D comment is reply of C comment. I want to tag C comment's author name in D comment. Because I don't want to add level 2.

But how do I store data in adapter? As you can see there's no level. So far what I wrote is: /Edited/

  for(int i = 0; i < result.getComments().size(); i++){
                    Comment comment = result.getComments().get(i);
                    if(comment.getComment_parent().equals("0")) continue;
                    String parentId = comment.getComment_parent();
                    boolean parentFound = false;
                    boolean rootFound = false;

                    while(!parentFound || !rootFound){

                        int parentPosition = binarySearch(result.getComments(),0, result.getComments().size(), parentId);
                        if(parentPosition == -1) break;
                        Comment temp = result.getComments().get(parentPosition);

                        if(temp.getComment_ID().equals(parentId)){
                            if (!parentFound){
                                parentFound = true;
                                comment.setTag(temp.getComment_author());
                            }

                            if (temp.getComment_parent().equals("0")) {
                                rootFound = true;
                                comment.setRootId(temp.getComment_ID());
                                temp.addChildComment(comment);
                            } else {
                                parentId = temp.getComment_parent();
                            }
                        }
                    }
                }


                Iterator itr = result.getComments().iterator();
                while (itr.hasNext()) {
                    Comment comment = (Comment) itr.next();
                    if(!comment.getComment_parent().equals("0")){
                        itr.remove();
                    }
                }

private int binarySearch(List<Comment> arr, int l, int r, String x)
    {
        if (r>=l)
        {
        int mid = l + (r - l)/2;
        if (arr.get(mid).getComment_ID().equals(x))
            return mid;

        if (Integer.valueOf(arr.get(mid).getComment_ID()) > Integer.valueOf(x))
            return binarySearch(arr, l, mid-1, x);

        return binarySearch(arr, mid+1, r, x);
    }
    return -1;
}

public class Comment {

private String comment_ID;
private String comment_post_ID;
private String comment_author;
private String comment_author_email;
private String comment_author_url;
private String comment_author_IP;
private String comment_date;
private String comment_date_gmt;
private String comment_content;
private String comment_karma;
private String comment_approved;
private String comment_agent;
private String comment_type;
private String comment_parent;
private String user_id;
private boolean isSend = true;
private List<Comment> commentList;

private String rootId;
private String tag;

Upvotes: 0

Views: 217

Answers (3)

Stan
Stan

Reputation: 6571

you should create 2 classes - one for Retrofit to parse WebAPI response to and the Comment entity itself.
The following is a class for Retrofit response:

public class Comments{
    @SerializedName("comment_count")
    private int commentCount; //this could be ignored
    private List<Comment> comments;
}

@SerializedName("comment_count") tells Retrofit the JSON key to commentCount field, without this annotation you have to declare field with the same name as JSON key, like private int comment_count;
The Comment entity itself:

public class Comment {

    private String comment_ID;
    private String comment_post_ID;
    private String comment_author;
    private String comment_author_email;
    private String comment_author_url;
    private String comment_author_IP;
    private String comment_date;
    private String comment_date_gmt;
    private String comment_content;
    private String comment_karma;
    private String comment_approved;
    private String comment_agent;
    private String comment_type;
    private String comment_parent;
    private String user_id;
    private boolean isSend = true;
}

You don't have to parse response yourself, let this job to be done by Retrofit and you will get List<Comment> which you could use to fill your adapter freely or store this array into DB.

The following shows you how to get response using Retrofit. Somewhere in your code you call method

private void requestComments() {
    ApiManager.getCommentsAdapter().getComments(new IApiCallBackSuccess<Comments>() {
        @Override
        public void onApiSuccess(Comments response) {
            onGotComments(response); // do there whatever you like
        }
    }, this);
}

in ApiManager:

public final class ApiManager {
    public static CommentsApiAdapter getCommentsAdapter() {
        return new CommentsApiAdapter();
    }
}

CommentsApiAdapter:

public class CommentsApiAdapter extends MyApiAdapter<CommentsApiService> {

    @Override
    Class<CommentsApiService> provideServiceClass() {
        return CommentsApiService.class;
    }

    public void getComments(final IApiCallBackSuccess<Comments> callBackSuccess,
                             final IApiCallBackError callBackError) {
        getService().getComments().enqueue();
    }
}

MyApiAdapter, ApiUrlHelper.BASE_URL - is just a static final string with base url like "www.mywebapi.com"

public abstract class MyApiAdapter<ApiService> extends BaseApiAdapter<ApiService> {

    @Override
    String getBaseUrl() {
        return ApiUrlHelper.BASE_URL;
    }
}

CommentsApiService (representing Retrofit service)

public interface CommentsApiService {

    @GET("/api/comments")
    Call<Comments> getComments();
}

BaseApiAdapter

abstract class BaseApiAdapter<ApiService> {

    private final int TIME_OUT = ApiUrlHelper.TIME_OUT;
    private final ApiService mApiService;
    private final Gson mGson;

    BaseApiAdapter() {
        final OkHttpClient.Builder okClientBuilder = new OkHttpClient.Builder()
                .connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
                .readTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
                .writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS);


        mGson = gsonBuilder.create();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(getBaseUrl())
                .addConverterFactory(GsonConverterFactory.create(mGson))
                .client(okClientBuilder.build())
                .build();
        mApiService = retrofit.create(provideServiceClass());
    }

    abstract Class<ApiService> provideServiceClass();
}

Upvotes: 0

MD Naseem Ashraf
MD Naseem Ashraf

Reputation: 1028

Simply use the jsonschema2pojo converter tool to get your plain old java object. This will give you a very effective data object as per your API response which you can further extend with whatever required logic in your application.

Upvotes: 0

Jaykishan Sewak
Jaykishan Sewak

Reputation: 822

Dont create Model class manually, I will suggest you to make Model/POJO classes using ROBOPOJO Generator It will generate All model classes for you, you don't need to make it by your self, Will also help you in future while creating model class. It just need JSON string and click will make your job done

Upvotes: 2

Related Questions