I just got the awesome error “fb.login called before fb.init” and remembered all the things i learned @knallgrau why this error could happen but found no solution. Here is why i still got it. And why it took me hours to find it.
what i tried
If you follow the instructions on https://developers.facebook.com/docs/reference/javascript/ and copy paste facebook’s initialization and loading code into one of your closure-classes you’ll get the typical error mentioned above.
Unfortunately fb.init fails silently not telling you why it could not initialize. So i remembered the reasons why i got this error earlier and checked:
- if i included all.js more than once
- if the app id was wrong
- if the app settings were incorrect (no trailing “/”, wrong domain-name, wrong sandbox settings, etc, etc)
nothing was wrong with that. i even wrote the app id into the init-command literally. did not work.
what was wrong
I was desperate. In google closure to preserve names for externs you have to store the function via array access:
window['fbAsyncInit'] = function() { FB.init({appId: 1234567890}); };
This was the only difference i made from copy pasting it to my closure class (ok in the code above i removed some lines). Finally i figured i could check if the correct function is written into the global fbAsyncInit. So i went to my console (had to clear millions of lines of hopeless debugging attempts) and typed “window.fbAsyncInit”. And what did i see???
Google Closure played with my code!
function $window$fbAsyncInit$() { FB.init({$appId$:1234567890, $channelUrl$:"/channel.html", status:!1, $xfbml$:!0, $oauth$:!0, cookie:!0, $logging$:!0}); }
of course $appId$ resolved to ‘appId’, but this was the exact problem!
The solution
So the next step was easy: use string literals for my plain object!
window['fbAsyncInit'] = function() { FB.init({'appId': 1234567890}); };
worked like charm.