how to properly inject Facebook JavaScript SDK to AngularJS controllers?

邮差的信 提交于 2019-12-02 20:40:48

I have actually had to do this... I don't have the code with me, and it's probably proprietary anyhow... but it was essentially like this:

// create a simple factory:    
app.factory('facebook', ['$window', function($window) {

    //get FB from the global (window) variable.
    var FB = $window.FB;

    // gripe if it's not there.
    if(!FB) throw new Error('Facebook not loaded');

    //make sure FB is initialized.
    FB.init({
       appId : 'YOUR_APP_ID'
    });

    return {
        // a me function
        me: function(callback) {
            FB.api('/me', callback);
        }

        //TODO: Add any other functions you need here, login() for example.
    }
}]);

// then you can use it like so:
app.controller('SomeCtrl', function($scope, facebook) {

    //something to call on a click.
    $scope.testMe = function() {

       //call our service function.
       facebook.me(function(data) {
          $scope.facebookUser = data;

          //probably need to $apply() this when it returns.
          // since it's async.
          $scope.$apply();
       });
    };
});

If there are any errors in that let me know, and I'll look up the working code I have and see what I've missed. But that should be about it.

2015 EDIT !

This is an old answer. I'll suggest you check out how the popular angular-modules on github do it or simply use them:

Old Answer

Because of problems with calls at the start of the app I use the following approach, which loads the app only after the SDK has been loaded:

window.fbAsyncInit = function () {
FB.init({
    appId: window.fbConfig.appID,
    channelUrl: '//' + window.location.hostname + window.location.pathname + 'channel.php',
    status: window.fbConfig.oInitOptions.bStatus || true,
    cookie: window.fbConfig.oInitOptions.bCookie || true,
    xfbml: window.fbConfig.oInitOptions.bXfbml || true
});


// Get Login Status once at init
window.FB.getLoginStatus(function (oResponse) {
    if (oResponse && oResponse.status) {
        window.fbConfig.sAuthStatus = oResponse.status;
    }

    // Bootstrap app here only after the sdk has been loaded
    angular.bootstrap(document.body, ['fbAngularApp']);
});
};

// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
    return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = '//connect.facebook.net/' + window.fbConfig.lng + '/all.js';
ref.parentNode.insertBefore(js, ref);
}(document));

I have written this angularjs-facebook service. First you init it on your app module config method to initialize your facebook app id and other settings.

Then you just enjoy calling the Facebook service from Controllers and calling Facebook methods asynchronous just as normal.

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

The only way that works is including the the sdk in your index page in the old way.

Because I have implemented the same solution from @blesh or extended version from @elviejo, both of them has a problem if we have a function which is called when the controller is invoked, the chance that FB is not initialized is very high and this will make the call failed while calling a function from undefined :)

Hope this will help others avoiding headache with this.

I was stumped on this for a while, I solved it with a $watch

//setup watch for FB API to be ready
//note that since you use $window, you need to inject it into your controller
//angular.module('myApp').controller('appController', function ($scope, $window, ...) {
$scope.FBListener = $scope.$watch(function () {
  return $window.FB;
}, function (newVal, oldVal) {
  // FB API loaded, make calls
  console.log("FB is ready");
  //functions that do FB API calls
  $scope.getFBEvents();
  $scope.getFBPosts();
});

when FB has been loaded, you can clear the $watch (which is probably best to do for performance) by calling $scope.FBListener();

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!