Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Working with asynchronously loaded javascript

Pivotal Labs
Wednesday, September 1, 2010

My pair and I were recently working on an app that asynchronously loaded the Facebook Javascript SDK but synchronously loaded the jQuery library. We had to invoke some javascript once Facebook and jQuery were both loaded, and this post describes how we did it.

First, we followed Facebook’s recommendation and asynchronously loaded the Facebook SDK right after the start of the body tag. Then for other reasons we put all other javascript includes right before the end of the body tag. The resulting html looked like this:

<html>
  <head>
  </head>
  <body>
    <div id="fb-root"></div>
    <script>
      (function() {
        var e = document.createElement('script');
        e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
        e.async = true;
        document.getElementById('fb-root').appendChild(e);
      }());
    </script>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  </body>
</html>

When the Facebook js loads, it looks for a function named fbAsyncInit and invokes it if it’s there. When jQuery detects that the document has loaded, it triggers a document ready event. Since the Facebook js is being loaded asynchronously, though, the sequence of these events is unpredictable. Things could happen in one of 2 ways:

  1. fbAsyncInit is called then $(document).ready() is triggered
  2. $(document).ready() is triggered then fbAsyncInit is called

We needed to run code once Facebook and jQuery were both loaded. If Facebook loaded first, this code worked:

$(document).ready(function(){
  $("#content").html("Welcome!")
  FB.init({
    appId  : 'YOUR APP ID',
    status : true,
    cookie : true,
    xfbml  : true
  });
});

However, if Facebook hadn’t loaded, it blew up on FB being undefined.

If jQuery loaded first, then this code worked:

window.fbAsyncInit = function() {
  $("#content").html("Welcome!")
  FB.init({
    appId  : 'YOUR APP ID',
    status : true,
    cookie : true,
    xfbml  : true
  });
}

However, if jQuery hadn’t loaded, it blew up on $ being undefined.

After a bit of head scratching we came up with this:

$(document).ready(function(){
  function init(){
    $("#content").html("Welcome!")
    FB.init({
      appId  : 'YOUR APP ID',
      status : true,
      cookie : true,
      xfbml  : true
    });
  }

  if(window.FB) {
    init();
  } else {
    window.fbAsyncInit = init;
  }
});

On document ready, if Facebook is loaded, invoke the function immediately. If Facebook is not loaded, define the fbAsyncInit function, which will be called when Facebook loads.

Going one step further, we moved the page-specific javascript into an event listener, then triggered a custom event that page-specific js could listen for:

$(document).ready(function(){
  function facebookReady(){
    FB.init({
      appId  : 'YOUR APP ID',
      status : true,
      cookie : true,
      xfbml  : true
    });
    $(document).trigger("facebook:ready");
  }

  if(window.FB) {
    facebookReady();
  } else {
    window.fbAsyncInit = facebookReady;
  }
});

// elsewhere in the code
$(document).live("facebook:ready", function(){
  $("#content").html("Welcome!")
});

Thanks to Evan Farrar and Rachel Heaton for making this work!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

3 Comments

  1. Pingback: kibernick.com » How To: Use the Facebook Graph API to Power a Simple Social App

  2. Oytun says:

    I cant belive this solved my login problem when migrating from local to server…

    February 22, 2013 at 6:46 am

  3. Shabith says:

    thanks for the great code. This fixed the issue I had :)

    April 18, 2013 at 5:22 am

Add New Comment Cancel reply

Your email address will not be published.

Pivotal Labs

Pivotal Labs

Recent Posts

  • Does the set of all sets contain itself?
  • Standup 3/8/2012
  • Standup 3/7/2012
Subscribe to Pivotal's Feed

Author Topics

riddles (1)
agile (167)
capistrano (2)
rails (26)
movember (1)
git (10)
railsdoc (1)
object-design (1)
bdd (3)
cucumber (3)
linkedin (1)
oauth (1)
ruby (17)
tdd (2)
lvh.me (1)
rails 3.1.1 (1)
selenium (6)
homebrew (1)
mysql (5)
rvm (1)
sproutcore (1)
paperclip (2)
pry (1)
amazon (1)
heroku (1)
rails3 (2)
jasmine (3)
design (3)
process (12)
productivity (8)
learning (1)
olin (1)
migrations (2)
mongodb (2)
devise (2)
javascript (13)
rubymine (4)
ipad (1)
whurl (1)
head.js (1)
pairing (2)
tools (4)
pair programming (1)
rspec (10)
rspec2 (1)
ruby19 (1)
incubation (3)
startup (5)
api (1)
presenter (1)
vanna (1)
pivotal tracker (5)
capybara (1)
fakeweb (1)
webmock (1)
intern (1)
ruby on rails (25)
meetup (1)
textmate (1)
testing (20)
solr (4)
nyc-standup (11)
community (1)
opensource (3)
activerecord (4)
chrome (1)
mp4 (1)
activeresource (1)
flash (3)
neo4j (1)
nginx (1)
rsoc (1)
meta programming (1)
agile standup (7)
government (3)
webos (4)
xss (1)
jquery (1)
bundler (2)
ci (3)
gems (5)
postgresql (1)
geminstaller (1)
gemcutter (1)
cloud (2)
rack (2)
refraction (1)
gem (5)
refactoring (1)
validations (1)
webrat (1)
engine-yard (1)
firefox (2)
jsunit (1)
mongrel (2)
thin (1)
unicorn (1)
facebook (1)
rubygems (5)
jruby (1)
actioncontroller (1)
rails 2.3 (1)
palmpre (1)
autotest (1)
mac (2)
hosting (1)
goruco (11)
database (3)
railsconf (11)
gogaruco (4)
deployment (4)
github (1)
ie (1)
ajax (1)
intellij (1)
json (1)
asset packaging (1)
polonium (1)
character encoding (1)
utf-8 (1)
test (3)
civics (1)
hpricot (1)
rake (3)
sms (1)
unicode (1)
iphone (1)
java (1)
safari (1)
memory leaks (1)
rr (3)
editor (1)
css (1)
nyc (3)
performance (5)
fun (5)
enterprise rails (1)
health (1)
new and cool (1)
general (2)
treetop (1)
errors (1)
stack (1)
trace (1)
cache (1)
cookies (1)
freesoftware (1)
conferences (1)
development (1)
driven (1)
proxy (1)
caching (1)
peertopatent (1)
languages (1)
rest (2)
rubyforge (1)
sake (1)
file (1)
upload (1)
constants (1)
osx (1)
terminal (1)
pairprogramming (2)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >