Make FB.api() calls synchronous

12,034

Solution 1

If you think about it, you don't really want to make it synchronous. Javascript is single threaded by nature, making something that is asynchronous synchronous, would involve "freezing" the thread until the asynchronous call returns.

Even if you could do it, you don't want to, trust me.

Redesign your code to work with the asynchronous nature instead of fighting it. you will create better applications, have happier users and become a better coder all at the same time.

Solution 2

As commented elsewhere, making a synchronous call is useful if you want to open a popup after a successful response as browsers will often block popups that aren't a result of a direct user action.

You can do this by manually calling the Open Graph API with JavaScript (or jQuery as per the example below) rather than using the Facebook JS SDK.

e.g. to upload a photo via the Open Graph API and then prompt the user to add it as their profile picture using a popup, without the popup being blocked:

$.ajax({
    type: 'POST',
    url: 'https://graph.facebook.com/me/photos',
    async: false,
    data: {
        access_token: '[accessToken]',//received via response.authResponse.accessToken after login
        url: '[imageUrl]'
    },
    success: function(response) {
        if (response && !response.error) {
            window.open('http://www.facebook.com/photo.php?fbid=' + response.id + '&makeprofile=1');
        }
    }
});
Share:
12,034
Kevindra
Author by

Kevindra

Updated on June 29, 2022

Comments

  • Kevindra
    Kevindra almost 2 years

    I am creating fQuery API on top of FB javascript SDK. And till now everything worked fine, but i got stuck in FB.api calls now.

    Actually, I am trying to load facebook user object i.e. "/me" using FB.api function.

    function somefunc() {
      var r = fQuery.load(selector);  //selector = "me"
      return r;
    }
    
    
    fQuery.load = function( selector )  {
      fQuery.fn.response = "";
    
      return FB.api( "/" + selector, function (response) {
        // we get response here.
      });
    }
    

    Is it possible to return the response or can we make it sync call. I have tried many ways to work around but could not get success.

    Please provide suggestions.

  • changokun
    changokun about 13 years
    "argh," i originally thought. I hate answers like this that don't answer the question, but just say, "do it proper" with little guidance. but i am glad i took your advice, it solved some other problems. if it helps anyone else, i had to make the calling function also asynchronous, and break off some of the code to be called in a callback after operations had finished.
  • Sean Kinsey
    Sean Kinsey almost 13 years
    -1 That is just wrong - you block the tread, and will eventually get a stack overflow exception..
  • J-Rou
    J-Rou over 12 years
    I wasn't expecting that answer to be the accepted one. I know its not recommended, but still, I kind wanted to do it that way with the first call. To redesign my code will take forever. I need to make only one specific fb.api call (that is a very fast call) synchronous. I had already profiled the call and it was very fast.
  • Gelin Luo
    Gelin Luo about 12 years
    There are cases that you do need synchronous api, say I am creating a jquery validation rule, and I need query the result of graph api all to know if it's valid or not. Any suggestion on how to redesign the code to meet this requirement?
  • James Billingham
    James Billingham over 11 years
    1. This isn't an answer to the actual question. 2. One example where this is required is when dealing with avoiding popup blocking due to opening windows in different threads...
  • Martin Jespersen
    Martin Jespersen over 11 years
    You are missing the point - it is impossible to turn an async call into a sync call, period.
  • goerwin
    goerwin over 9 years
    Oh god, the answers we have to see :D
  • chuycepeda
    chuycepeda over 8 years
    just saw this post and it helped, but updated url must begin like "graph.facebook.com/v2.5"