Mohammad Nouri Mohammad Nouri - 3 months ago 13
Android Question

Why not show posts from server when use Retrofit in Android

I want to use

Retrofit
to load data from server, and I use
DataModel
for set and get data.

This is what I would like to do. When I click on a Category, I want to see posts from this category in the other
Activity
.

For showing category posts I use this link : http://tellfa.com/tafrihgah/?json=get_category_posts

For filtering I use
category id
.

For example : http://tellfa.com/tafrihgah/?json=get_category_posts&id=1 by this link i see all of posts from Category1.


My
Retrofit interface
for set link: (I set
base_url
in other class)

public interface Retrofit_ApiInterface {

// For Categories Response
@GET("tafrihgah/?json=get_category_posts&")
Call<R_CatModelResponse> getCatResponse(@Query("id") Integer id);
}


I send category id to other activity by this code :

public class ColoniesAdapter extends RecyclerView.Adapter<ColoniesAdapter.ViewHolder> {

private List<Retrofit_ColoniesModel> mDateSet;
private Context mContext;
private SparseBooleanArray expandState = new SparseBooleanArray();

public ColoniesAdapter(Context context, List<Retrofit_ColoniesModel> dataSet) {
this.mContext = context;
this.mDateSet = dataSet;
for (int i = 0; i < mDateSet.size(); i++) {
expandState.append(i, false);
}
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View view = LayoutInflater.from(mContext).inflate(R.layout.colonies_row, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {

holder.colonies_title.setText(mDateSet.get(position).getTitle());
holder.colonies_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getPosition();
Retrofit_ColoniesModel model = mDateSet.get(pos);
mContext.startActivity(new Intent(v.getContext(), Category_page.class)
.putExtra("categoryTitle", model.getTitle())
.putExtra("categoryID", model.getId()));

Toast.makeText(mContext, " " + model.getId(), Toast.LENGTH_SHORT).show();
}
});

...


Category_page code:

public class Category_page extends AppCompatActivity {

private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private TextView toolbar_title;
private ImageView toolbar_menuImage;
private RelativeLayout root;
private CategoryAdapter mAdapter;
private RecyclerView cat_recyclerView;
private LinearLayoutManager mLayoutManager;
private RelativeLayout loadLayout;
private String catTitle = "";
private Integer catID;
private Bundle bundle;
private int pageCount = 1;
private Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_page);
//if (!EventBus.getDefault().isRegistered(this)) {
// EventBus.getDefault().register(this);
//}

// Hide StatusBar color
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

// Initializing
context = Category_page.this;
toolbar = (Toolbar) findViewById(R.id.category_toolbar);
cat_recyclerView = (RecyclerView) findViewById(R.id.category_recycler);
toolbar_title = (TextView) toolbar.findViewById(R.id.toolbar_pages_title);
mLayoutManager = new LinearLayoutManager(this);
root = (RelativeLayout) findViewById(R.id.category_root);
loadLayout = (RelativeLayout) findViewById(R.id.category_empty_layout);
// Toolbar
setSupportActionBar(toolbar);
if (toolbar != null) {
getSupportActionBar().setTitle("");
}

// Receive Data
bundle = getIntent().getExtras();
catID = bundle.getInt("categoryID");
if (bundle != null) {
catTitle = bundle.getString("categoryTitle");
}
if (catTitle != null) {
toolbar_title.setText(catTitle);
}

// Load data
//LoadData(catID);
// Menu
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
toolbar_menuImage = (ImageView) toolbar.findViewById(R.id.toolbar_pages_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), toolbar_menuImage)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView
cat_recyclerView.setLayoutManager(mLayoutManager);
cat_recyclerView.setHasFixedSize(true);

// Retrofit //////////
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatResponse(catID);

call.enqueue(new Callback<R_CatModelResponse>() {
@Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
List<R_CatModel> models = response.body().getCat_posts();

mAdapter = new CategoryAdapter(context, cat_recyclerView, models);
cat_recyclerView.setAdapter(mAdapter);

Toast.makeText(Category_page.this, "Response", Toast.LENGTH_SHORT).show();
}

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

Toast.makeText(Category_page.this, "Error", Toast.LENGTH_SHORT).show();

}
});


I send category_id with below code from one adapter :

mContext.startActivity(new Intent(v.getContext(), Category_page.class)
.putExtra("categoryTitle", model.getTitle())
.putExtra("categoryID", model.getId()));


and receive this data with below code :

// Receive Data
bundle = getIntent().getExtras();
catID = bundle.getInt("categoryID");


But Error message (
Toast
) instead of category posts!

show error toast from :

@Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
Toast.makeText(Category_page.this, "Error", Toast.LENGTH_SHORT).show();
}


Update :

This is the error I get, :

E/CatResponseError: Error : com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 48 path $.category


Update #2 :

Added my POJO class :

public class R_CatModelResponse {

@SerializedName("status")
public String Cat_status;
@SerializedName("count")
public int Cat_count;
@SerializedName("pages")
public int Cat_pages;
@SerializedName("category")
public List<Retrofit_ColoniesModel> category;
@SerializedName("posts")
public List<R_CatModel> Cat_posts;

public String getCat_status() {
return Cat_status;
}

public void setCat_status(String cat_status) {
Cat_status = cat_status;
}

public int getCat_count() {
return Cat_count;
}

public void setCat_count(int cat_count) {
Cat_count = cat_count;
}

public int getCat_pages() {
return Cat_pages;
}

public void setCat_pages(int cat_pages) {
Cat_pages = cat_pages;
}

public List<Retrofit_ColoniesModel> getCategory() {
return category;
}

public void setCategory(List<Retrofit_ColoniesModel> category) {
this.category = category;
}

public List<R_CatModel> getCat_posts() {
return Cat_posts;
}

public void setCat_posts(List<R_CatModel> cat_posts) {
Cat_posts = cat_posts;
}
}


How can I fix this?

Please help me. Thanks in advance.

Answer

See this pattern which make your life easier:D, based on that use following structure:

Your data model should be:

public class Model {

    String status;
    int count;
    int page;
    Category category;
    List<Post> posts;

    // implement rest of thing

    public class Category{

        int id;
        String slug;
        String title;
        String description;
        int parent;
        int post_count;
    }

    public class Post {
        int id;
        String type;
        String slug;
        //..rest of thing
    }

}

Your service interface should be:

public interface IService {

        @GET("/tafrihgah/?json=get_category_posts")
        Call<Model> getCategoryPost(
                @Query("id") String id

                //...other query if you need should added like below
               @Query("categorySlug") String categorySlug,
               @Query("tag") String tag,
        );
    }

And your ServiceHelper contains following method:

public Call<CategoryModel> getAllCategory() {
    return service.getCateogryPost();
}

And your error cause your POJO is not fitted to server Model. Double check your Model and make sure Object instead of List/Array;

In your case instead of List<Retrofit_ColoniesModel> category use Retrofit_ColoniesModel category;

Comments