AngularJS – Asynchronous call to Facebook API

All we need is an easy explanation of the problem, so here it is.

I’am trying to call a Facebook API with AngularJS.

The problem is that all calls from FB API is Asynchronous, so I need to know when my query on facebook is avaliable to use in agularjs.

For this, I call this method in my controller:

Facebook.getLoginStatus();

which Facebook is my service, defined as:

app.factory(‘Facebook’, function() {

    getLoginStatus: function() {

        FB.getLoginStatus(function(stsResp) {
            console.log(stsResp);
            if(stsResp.authResponse) {
                // User is already logged in
                return true;
            } else {
                // User is not logged in.
                return false;
            }
        });
    }

}

What I want in this case is to check if user is logged. If true, I’ll show some options, otherwise, I’ll show the Login button.

I’ve already try to use $q.defer() functions, promises, factorys to watch response data, everything. But anything works as I want. I’ve checked some development examples based on Egghead.io examples, but I think that I’m not fully understand asynchronous calls in angularjs.

Thanks in advance.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Here’s a full basic working example of wrapping the Facebook API in an Angular service:

http://plnkr.co/edit/0GRLdWPJOzGFY14irxLT?p=preview

See also my answer to this question (which has some partial examples of Angular-FB integration):

AngularJS : Where to use promises?

Method 2

if you want to have all fb code in a slightly more angularish style, consider doing something like encapsulating the FB classes in a provider. FB is one rare example where the provider pattern is actually nice to use (to setup your app ID on the config section).

here’s an example of an angular facebook provider with basic login functionality and generic method for making graph api calls:

app.provider('facebook', function() {
  var fbReady = false
  this.appID = 'Default';

  function fbInit(appID) {
    (function(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));  
    window.fbAsyncInit = function() {
     FB.init({
      appId      : appID,
      cookie     : true,  
      xfbml      : true,  
      version    : 'v2.0' 
    });
     fbReady = true;
   }   
 }

 this.setAppID = function(appID) {
  this.appID = appID;
};

this.$get = function() {
  var appID = this.appID;
  var self = this;
  fbInit(appID);

  return {
    graph : function(path, cb) {
      FB.api(path, function(response) {
        cb(response);
      });
    },
    getAuth: function() {
      return self.auth;
    },
    getLoginStatus: function(cb) {
      if (!fbReady) {
        setTimeout(function() { 
          self.$get()['getLoginStatus'](cb);
        } , 100);
        console.log('fb not ready');
        return;
      }
      FB.getLoginStatus(function(response) {
        cb(response);
      });
    },
    login: function(cb) {
      if (!fbReady) {
        self.$get()['login'](cb);
        console.log('fb not ready');
        return;
      }
      FB.login(function(response) {
        if (response.authResponse) {
          self.auth = response.authResponse;
          cb(self.auth);
        } else {
          console.log('Facebook login failed', response);
        }
      }, {"scope" : "manage_notifications"});

    },
    logout: function() {
      FB.logout(function(response) {
        if (response) {
          self.auth = null;
        } else {
          console.log('Facebook logout failed.', response);
        }

      });
    }
  }
}
});

later when you want to use it, simply set your app’s ID in the config section:

app.config(function(facebookProvider){
 facebookProvider.setAppID('<your_app_id>');
})

inject it to a controller:

.controller('MainCtrl', function ($scope, facebook) {

and then perform some calls in a controller/run section:

facebook.graph('/me/notifications', onNotificationsGotten);

Method 3

I wrote this module angularjs-facebook as a provider, such that on config you configure your app id and then you can use facebook asynchronous calls. There are also methods to listen on controllers.

https://github.com/ciul/angularjs-facebook

Method 4

Heres a good example of making asynchronous http requests with the iTunes API. It should help you figure out how to do it with the Facebook API as well.

Asynchronous HTTP requests in Angular JS

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply