skip to Main Content

I am using the Facebook graph api to find out what pages a user is apart of. When the query comes back with a json object it has what I need but, for some reason it doesn’t want to add to my array list. The correct value is printed in log.d it seems to skip my arraylist for some reason. Any ideas?

Find page function

private ArrayList<String> foundPages;
private JSONObject jsonObject; 

public ArrayList<String> findPages()
{
    accessToken = AccessToken.getCurrentAccessToken();
    foundPages = new ArrayList<>();

    GraphRequest request = GraphRequest.newGraphPathRequest(
            accessToken,
            "/me/accounts",
            new GraphRequest.Callback() {
                @Override
                public void onCompleted(GraphResponse response) {

                    try {

                        jsonObject = response.getJSONObject();
                        for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
                        {
                         page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
                            Log.d("viewmodel",page);
                            foundPages.add(page);

                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });

    request.executeAsync();


    return foundPages;
} 

2

Answers


  1. Yep. This here:

    request.executeAsync();
    

    triggers an asynchronous request. But your “current” thread simply continues to do:

    return foundPages;
    

    and it returns an empty list.

    That list gets later filled, but at the moment in time when that method returns, that list is still empty. Or just gets filled. Who knows, as it gets filled asynchronously, at some unknown point in the future.

    A solution could be to have some other variable/field that tells you the data has arrived and pushed into the list.

    Alternatively, that method could just make a synchronous request, simply block the caller from progressing until the data has arrived.

    You see, you can’t have it both ways: when you don’t wait for your results to arrive, you shouldn’t expect them to be available immediately.

    Login or Signup to reply.
  2. There is a common way to solve this problem, which is to define a callback method which will return these values to you, AFTER they have been populated by the call, which goes something like this (my java is rusty, bear with me…)

    define an interface :

     interface Callback{
            void apiResponseCallback(ArrayList<Page> result);//whatever your model is, make the array of that type
        }
    

    then, in your normal findPages method, change it to this:

    public void findPages(Callback callback) {
        //
        // 
        ........
         for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
                        {
                         page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
                            Log.d("viewmodel",page);
                            foundPages.add(page);
    
                        } 
        callback.apiResponseCallback(foundPages);//here we are returning the data when it is done
    }
    

    then, when you call findPages

    findPages(new Callback() {
            @Override
            public void apiResponseCallback(ArrayList<Page> result) {
                here, this result parameter that comes through is your api call result to use, so result will be your populated pages to use.
            }
        });
    }
    

    sake of completeness:

    public void findPages(Callback callback)
    {
        accessToken = AccessToken.getCurrentAccessToken();
        foundPages = new ArrayList<>();
    
        GraphRequest request = GraphRequest.newGraphPathRequest(
                accessToken,
                "/me/accounts",
                new GraphRequest.Callback() {
                    @Override
                    public void onCompleted(GraphResponse response) {
    
                        try {
    
                            jsonObject = response.getJSONObject();
                            for(int i=0; i < jsonObject.getJSONArray("data").length(); i++)
                            {
                             page = response.getJSONObject().getJSONArray("data").getJSONObject(i).getString("name");
                                Log.d("viewmodel",page);
                                foundPages.add(page);
    
                            }
                            callback.apiResponseCallback(foundPages);
    
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
    
        request.executeAsync();
    } 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search