Reputation: 10110
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.
Upvotes: 2
Views: 13232
Reputation: 6561
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);
Upvotes: 4
Reputation: 27
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
Upvotes: 1
Reputation: 623
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
Upvotes: 3
Reputation: 7998
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?
Upvotes: 8