0

I am working on an android app. I want to retrieve json data into an ArrayList of my data model called Expert.

Here is the code on the onCreate() method

mExpertsList = new ArrayList<Expert>();
loadData();
Log.v("RESPONSE", Integer.toString(mExpertsList.size()));

Here is the code in the function retrieving json data.

private void loadData(){

    RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
            null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                JSONArray jarray = response.getJSONArray("actors");
                for (int i = 0; i < jarray.length(); i++) {
                    JSONObject object = jarray.getJSONObject(i);

                    Expert expert = new Expert();

                    expert.setImageUrl(object.getString("image"));
                    expert.setName(object.getString("name"));
                    expert.setTopic(object.getString("country"));
                    expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
                    expert.setDescription(object.getString("description"));

                    mExpertsList.add(expert);
                }
            }
            catch(JSONException e){
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

    queue.add(jsonObjectRequest);
}

Inside loadData() method the mExpertsList shows size of 6 at end of for loop. Checked this using log messages.

But a Log statement immediately after loadData() shows that mExpertsList has size of zero.

What am I missing here?

2
  • 1
    you have added the log statement in wrong place, your code is correct Commented Mar 15, 2018 at 11:39
  • API calls are asynchronous that's why you are not getting the desired result Commented Mar 15, 2018 at 11:41

5 Answers 5

1

JsonObjectRequest is an Asynchronous request so your list will be update on other thread . And you logged the size synchronously so it will print 0 always .

Access the List inside onResponse(JSONObject response);

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
        null, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
        try {
            JSONArray jarray = response.getJSONArray("actors");
            for (int i = 0; i < jarray.length(); i++) {
                JSONObject object = jarray.getJSONObject(i);

                Expert expert = new Expert();

                expert.setImageUrl(object.getString("image"));
                expert.setName(object.getString("name"));
                expert.setTopic(object.getString("country"));
                expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
                expert.setDescription(object.getString("description"));

                mExpertsList.add(expert);
            }
     Log.v("RESPONSE", mExpertsList.size());
        }
        catch(JSONException e){
            e.printStackTrace();
        }
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    }
});
Sign up to request clarification or add additional context in comments.

Comments

1
mExpertsList = new ArrayList<Expert>();  // You are initializing your list with size 0
loadData();  // Calling the API which will run in background

So whenever you are calling Log.v("RESPONSE", Integer.toString(mExpertsList.size()));just after loadData() method your mExpertsList is still of size 0.

Size will change only after you get your API response.

3 Comments

Actually I am using this mExpertsList as a data source for an adapter. I think JSONRequestObject is asynchronous and the empty list is being passed before data retrieval is complete. How do I make the program wait till loading is complete? Is this even a good practice? Else can I notify the adapter on completion of loading data?
set your adapter inside your public void onResponse(JSONObject response) class.
I simply called a mAdapter.notifyDataSetChanged() immediately after the for loop inside onResponse() listener method. That did the trick.
1

This is an Asynchronous operation, Volley will not wait for your response and execute your next code.

If you want to print Arraylist size then print it just after for loop,

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
    null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
    try {
        JSONArray jarray = response.getJSONArray("actors");
        for (int i = 0; i < jarray.length(); i++) {
            JSONObject object = jarray.getJSONObject(i);

            Expert expert = new Expert();

            expert.setImageUrl(object.getString("image"));
            expert.setName(object.getString("name"));
            expert.setTopic(object.getString("country"));
            expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
            expert.setDescription(object.getString("description"));

            mExpertsList.add(expert);
        }
 Log.v("RESPONSE", mExpertsList.size());
        }
        catch(JSONException e){
            e.printStackTrace();
        }
    }
    }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    }
});

It will print the exxact size of your list.

Comments

0

It looks like you are making some kind of asynchronous call when you call loadData():

mExpertsList = new ArrayList<Expert>();
loadData();
Log.v("RESPONSE", Integer.toString(mExpertsList.size()));

When you check the size, it is possible that onResponse(), the handler for the web call, has not yet been called. If so, then the size would still appear to be zero.

You should only be relying on the contents of mExpertsList being there if onResponse has been successfully called with actual content.

Comments

0

Do this change in part 1:

mExpertsList = new ArrayList<Expert>();
loadData();
//Log.v("RESPONSE", Integer.toString(mExpertsList.size()));----Comment it out

Change in part 2:

private void loadData(){

    RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
            null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                JSONArray jarray = response.getJSONArray("actors");
                for (int i = 0; i < jarray.length(); i++) {
                    JSONObject object = jarray.getJSONObject(i);

                    Expert expert = new Expert();

                    expert.setImageUrl(object.getString("image"));
                    expert.setName(object.getString("name"));
                    expert.setTopic(object.getString("country"));
                    expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
                    expert.setDescription(object.getString("description"));

                    mExpertsList.add(expert);


                    Log.v("RESPONSE", Integer.toString(mExpertsList.size())); //-----New ADDED


                }
            }
            catch(JSONException e){
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

    queue.add(jsonObjectRequest);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.