How to detect when facebook's FB.init is complete
Update on Jan 04, 2012
It seems like you can't just call FB-dependent methods (for example FB.getAuthResponse()
) right after FB.init()
like before, as FB.init()
seems to be asynchronous now. Wrapping your code into FB.getLoginStatus()
response seems to do the trick of detecting when API is fully ready:
window.fbAsyncInit = function() { FB.init({ //... }); FB.getLoginStatus(function(response){ runFbInitCriticalCode(); });};
or if using fbEnsureInit()
implementation from below:
window.fbAsyncInit = function() { FB.init({ //... }); FB.getLoginStatus(function(response){ fbApiInit = true; });};
Original Post:
If you want to just run some script when FB is initialized you can put some callback function inside fbAsyncInit
:
window.fbAsyncInit = function() { FB.init({ appId : '<?php echo $conf['fb']['appid']; ?>', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session xfbml : true // parse XFBML }); FB.Canvas.setAutoResize(); runFbInitCriticalCode(); //function that contains FB init critical code };
If you want exact replacement of FB.ensureInit then you would have to write something on your own as there is no official replacement (big mistake imo). Here is what I use:
window.fbAsyncInit = function() { FB.init({ appId : '<?php echo $conf['fb']['appid']; ?>', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session xfbml : true // parse XFBML }); FB.Canvas.setAutoResize(); fbApiInit = true; //init flag }; function fbEnsureInit(callback) { if(!window.fbApiInit) { setTimeout(function() {fbEnsureInit(callback);}, 50); } else { if(callback) { callback(); } } }
Usage:
fbEnsureInit(function() { console.log("this will be run once FB is initialized");});
Actually Facebook has already provided a mechanism to subscribe to authentication events.
In your case you are using "status: true" which means that FB object will request Facebook for user's login status.
FB.init({ appId : '<?php echo $conf['fb']['appid']; ?>', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session xfbml : true // parse XFBML});
By calling "FB.getLoginStatus()" you are running the same request again.
Instead you could use FB.Event.subscribe to subscribe to auth.statusChange or auth.authResponseChange event BEFORE you call FB.init
FB.Event.subscribe('auth.statusChange', function(response) { if(response.status == 'connected') { runFbInitCriticalCode(); }});FB.init({ appId : '<?php echo $conf['fb']['appid']; ?>', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session xfbml : true // parse XFBML});
Most likely, when using "status: false" you can run any code right after FB.init, because there will be no asynchronous calls.
Here is a solution in case you use jquery and Facebook Asynchronous Lazy Loading:
// listen to an Event$(document).bind('fbInit',function(){ console.log('fbInit complete; FB Object is Available');});// FB Asyncwindow.fbAsyncInit = function() { FB.init({appId: 'app_id', status: true, cookie: true, oauth:true, xfbml: true}); $(document).trigger('fbInit'); // trigger event};