Proper way to include Facebook SDK for Javascript and jQuery …
… and avoid race condition! :)
Although fb is pretty clear on how to do it (http://bit.ly/2eGfFDv) – many developers are still doing it wrong. So this blog post is here to be reminder for me and others, also it will propose small upgrade to the fb recommended practice.
The naive and wrong way to do it
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script> window.fbAsyncInit = function() { FB.init({ appId : 'your-app-id', xfbml : true, version : 'v2.8' }); // do something with DOM and jQuery $('#loginbutton,#feedbutton').removeAttr('disabled'); FB.getLoginStatus(updateStatusCallback); }; (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')); </script>
The problem with this is the race condition: at the time fbAsyncInit gets called there is no guaranty that DOM is ready and that #loginbutton or #feedbutton is there, ready to be used.
This bug is hard to spot and debug – since it will not always manifest. It is very likely that you as developer with fast connection and computer will never experience this bug – but your clients (visitors) might.
So it is best not to leave this to chance since fix is so easy.
Facebook recommendation
Learn more: http://bit.ly/2eGfFDv
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script> $(document).ready(function() { $.ajaxSetup({ cache: true }); $.getScript('//connect.facebook.net/en_US/sdk.js', function() { FB.init({ appId: '{your-app-id}', version: 'v2.8' } ); $('#loginbutton,#feedbutton').removeAttr('disabled'); FB.getLoginStatus(updateStatusCallback); }); }); </script>
Problem with this approach is that you are changing global jQuery ajax cache settings.
The better way
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script> $(document).ready(function() { $.ajax( { url: '//connect.facebook.net/en_US/sdk.js', dataType: 'script', cache: true, success:function(script, textStatus, jqXHR) { FB.init( { appId : '{your-app-id}', xfbml : true, version : 'v2.8' } ); $('#loginbutton,#feedbutton').removeAttr('disabled'); FB.getLoginStatus(updateStatusCallback); } }); }); </script>
Now we did it. No race condition between jQuery, fb SDK for JS and loading of DOM. Also global jQuery Ajax settings are untouched.
Cheers! :)
One thought on “Proper way to include Facebook SDK for Javascript and jQuery …”
July 31, 2017 at 20:51
Thank you for the tip !
But check you will have in this case an “Uncaught ReferenceError: updateStatusCallback is not defined”.
Just replace with :
FB.getLoginStatus(function(){
alert(‘Status updated!!’);
// Your logic here
});
see: https://stackoverflow.com/questions/20986278/updatestatuscallback-not-defined-on-facebook-examble-of-jquery