facebookfacebook-javascript-sdkfacebook-fqlfacebook-batch-request

facebook batch/fql friendlists a friend is member of


I'm creating a javascript facebook app to have an overview of my friendlists. Actually I can retrieve my (logged in user = me) friendlists, when I click a friendlist I see all my friends in that list.

When I want now is, when I click a list, I want to see the friends belonging to that list, and a comma separated lists my friend is member of.

For example in the list "Best" I have 3 friends: Athos, Portos, Aramis. But they are also in other lists. So in my app I'd like to get something like this:

I tried with the FQL multiquery, but it seems impossible to get what I want.

So I think I should use a Batch request, but since I don't have a lot of experience using batches here I am asking your help.

So here the FQL query I use to get friends belonging to the list. I need this, because I want to manage friends beginning from a list:

var listID = 123;//just enter a listID
var friendsInList = 'SELECT uid,username,profile_url,first_name,last_name,pic_square FROM user WHERE uid IN (SELECT uid FROM friendlist_member WHERE flid =' + listID +')';

Now I don't know how to proceed in a clean and efficient way. I have a working but inefficient solution:

//[...]FB.api call to get a response object with all my friends using the friendsInList query above
for (var i = 0; i < response.length; i++) {
    friendID = response[i].uid;
    //call FB.api with the following query:
    var friendListMemberships = 'SELECT uid, flid, name FROM friendlist_member WHERE flid IN (SELECT flid FROM friendlist WHERE owner=me()) AND uid IN (select uid FROM friendlist WHERE flid =' + friendID;
}

the above solution works but is highly inefficient as I send a FB.api request for each friend, very slow for big lists... thus I'd like a pro user to help me putting this in a batch (a batch can have maximum 50 requests, thus I'd like to send just 1-2 requests and get back all what I need).

I know how to write a batch, here I put the structure of my code, if it can help you completing it with the second query:

var listID = _listID;

var _queryFriendsInList = 'SELECT uid,username,profile_url,first_name,last_name,pic_square FROM user WHERE uid IN (SELECT uid FROM friendlist_member WHERE flid =' + listID + ')';

var queryFriendsInList = _queryFriendsInList.replace(" ", "+");

var _queryFriendListMemberships = 'I have no idea what kind of query I can write here to get the lists my friends from queryFriendsInList are member of';

var queryFriendListMemberships = _queryFriendListMemberships.replace(" ", "+");

var searchArgs = {
    access_token: FB.getAuthResponse().access_token,
    batch: []
};

searchArgs.batch.push({
    'method': 'GET',
    'name': 'friendsInList',
    'relative_url': 'method/fql.query?query=' + queryFriendsInList,
    'omit_response_on_success': false
});

//here is where I need help
searchArgs.batch.push({
    'method': 'GET',
    'name': 'friendlistMememberships',
    'relative_url': 'method/fql.query?query=' + queryFriendListMemberships,
    'omit_response_on_success': false
});

FB.api("/", "POST", searchArgs,
function (response) {
    //console.log("log");
}
);

I hope the question and code samples are clear enough. Thank you for helping!


Solution

  • You can get everything you want in one API call with a multiquery. You'll need to assemble this together on the client side with a few loops, but it shouldn't be too hard. Here's the query:

    {
    "all_friendlists":
        "SELECT flid, owner, name FROM friendlist WHERE owner=me()",
    "fl_members":
       "SELECT uid, flid FROM friendlist_member WHERE flid IN 
          (SELECT flid FROM #all_friendlists)",
    "fl_member_details":
       "SELECT uid, name, username FROM user WHERE uid IN (SELECT uid FROM #fl_members)" 
    }
    

    You can present everything to your user from this one API call. The #all_friendlists query gives all your user's friendlists. Once your user has selected a friendlist, then loop through #fl_members to find all the members of this list, retrieving their details from #fl_member_details. Make another loop through #fl_members to find what other lists they belong to.

    Alternately, you could just mash these three lists together into a single presentation page, and use a jQuery data filtering scheme like Isotope to allow your user to sort/filter/etc. on the fly.