0

I'm new to Retrofit2, trying to parse an URL with an array, but it tries to parse it as an object so I get this message. Don't really know where exactly the problem lies.

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

I've been following this tutorial https://www.learn2crack.com/2016/02/recyclerview-json-parsing.html

Here is my Activity

public class WordActivity extends AppCompatActivity {
private ListView listView;
private TextView textView;
private RecyclerView recyclerView;
private ArrayList<WordRepo> data;
private WordRecyclerAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.word_info_layout);
    Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(myToolbar);
    getSupportActionBar().setTitle("");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    myToolbar.setTitle(Html.fromHtml("<font color='#272d85'>Svenska slangord </font>"));

    //textView = (TextView) findViewById(R.id.textView);
    //listView = (ListView) findViewById(R.id.listView);



    Bundle bundle = this.getIntent().getExtras();
    if (bundle != null) {

        if (bundle.containsKey("posID")) {
            int posid = bundle.getInt("posID");
            getRetro(posid + 1);
        }
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }
}

public void getRetro(int categoryID) {

    WordInterface client = ApiClient.getClient().create(WordInterface.class);
    Call<JSONResponse> call = client.getJSON(categoryID);
    call.enqueue(new Callback<JSONResponse>() {

        @Override
        public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
            recyclerView = (RecyclerView) findViewById(R.id.recycler_view_words);
            recyclerView.setHasFixedSize(true);
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
            recyclerView.setLayoutManager(layoutManager);

            JSONResponse jsonResponse = response.body();
            data = new ArrayList<>(Arrays.asList(jsonResponse.getList()));
            adapter = new WordRecyclerAdapter(data);
            recyclerView.setAdapter(adapter);
        }

        @Override
        public void onFailure(Call<JSONResponse> call, Throwable t) {
            Toast.makeText(WordActivity.this, "error" + t, Toast.LENGTH_LONG).show();
        }

    });
}

my Recycleradapter

public class WordRecyclerAdapter extends 
RecyclerView.Adapter<WordRecyclerAdapter.ViewHolder> {
private ArrayList<WordRepo> values;

public WordRecyclerAdapter(ArrayList<WordRepo> values) {
    this.values = values;
}

@Override
public WordRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.recyclerview_words, viewGroup, false);
            return new ViewHolder(view);
}

@Override
public void onBindViewHolder(WordRecyclerAdapter.ViewHolder viewholder, int i) {
    viewholder.word.setText(values.get(i).getWords());
    viewholder.description.setText(values.get(i).getDescription());
}

@Override
public int getItemCount() {
    return values.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView word, description;

    public ViewHolder(View view) {
        super(view);
        word = (TextView) view.findViewById(R.id.word);
        description = (TextView) view.findViewById(R.id.word_description);

    }
}

}

Interface

public interface WordInterface {
@GET("categories/{categoryID}/words")
Call<JSONResponse> getJSON(@Path("categoryID") int categoryID);
}

Getter/Setter

public class WordRepo {
private String name;
private String description;

public String getDescription() {
    return description;
}

public String getWords() {
    return name;
}


}

JSONResponse class

public class JSONResponse {

private WordRepo[] words;

public WordRepo[] getList() {
    return words;
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Albin Engberg
  • 11
  • 1
  • 5

1 Answers1

0

You just need to set response to your own ArrayList of your Object. I strongly recommend you define your class to get data.

In my case,

@Override
public void onResponse(Call<ResponseRidingLogs> call, Response<ResponseRidingLogs> response) {
    if(response.body().header.result_code != 0) {
        // Error handling
    } else { 
        ResponseRidingLogs responseRidingLogs = response.body();
        // I have my own header and body: inside body there is arraylist
       List<yourClass> = responseRidingLogs.body();
       //...
    }
    //...
}

public class ResponseRidingLogs {
    public HKRheader header;
    public List<RidingLog> body;
}

It's not important whether you add your own header and body in your own protocols or not. If you use your class definition for JSON communication, you don't need to look inside JSON protocol. You just define "the same class" with server developer.

Will Kim
  • 1
  • 2