FB is not defined, yet Javascript code runs smoothly - javascript

I've only started Javascript a few days ago, so this question might seem basic.
I've written some Javascript code to interact with the Facebook API.
The goal is to display all the pages managed by a user when he logs in via a Facebook login button.
The code seems to work as it does what it's supposed to do.
However, the console gives me the error "FB is not defined".
I've read all the other questions about this error and it seems to be linked to the asynchronous loading of the SDK, but i can't seem to figure this out.
How come i still get this error?
******EDIT 07/07/2017*******
Google Chrome's console gives me the "FB is not defined error" at the FB.getLoginStatus line of this portion of code:
function checkLoginStatus() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
} else {
document.getElementById('pageslist').style.display = 'none'; //Hides the div when people are not connected
document.getElementById('pagestatistics').style.display = 'none'; //Hides the div when people are not connected
}
});
}
It also points to the following part, which seems to be the issue since, when i remove it from the code, the error disappears:
//Here below, _5h0o is the class of the logout button
//This checks the login status AFTER the user clicks on logout thanks to setTimeout
document.getElementsByClassName('_5h0o').onclick = setTimeout(function() {
checkLoginStatus();
}, 100);
Here is the full code:
//Initialize Facebook SDK + Check Login Status
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxx',
xfbml : true,
version : 'v2.9'
});
checkLoginStatus();
};
(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/fr_FR/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
} (document, 'script', 'facebook-jssdk'));
</script>
//Facebook Login Button
<div class="fb-login-button" data-scope="public_profile, read_insights, pages_show_list" data-width="300" data-max-rows="1" data-size="large" data-button-type="login_with" data-show-faces="false" data-auto-logout-link="true" data-use-continue-as="false" onlogin="checkLoginStatusAfterLogin()" onclick="checkLoginStatus()"></div>
<script>
//Checks login status after people click on the Facebook button (useful for logout event)
function checkLoginStatus() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
} else {
document.getElementById('pageslist').style.display = 'none'; //Hides the div when people are not connected
}
});
}
//Checks login status after people log in via the Facebook button
function checkLoginStatusAfterLogin() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
document.getElementById('pageslist').style.display = 'inline-block';
} else {
checkLoginStatus();
}
});
}
//Here below, _5h0o is the class of the logout button
//This checks the login status AFTER the user clicks on logout thanks to setTimeout
document.getElementsByClassName('_5h0o').onclick = setTimeout(function() {
checkLoginStatus();
}, 100);
</script>
//Display the pages (in the form of clickable spans) for which the user has reading rights
<div id="pageslist"></div>
<script>
function getPagesList() {
FB.api('/me/accounts', {fields:'id, name'}, function(response){
document.getElementById('pageslist').innerHTML = ''; //Makes sure the div is cleared before populating it with the list of pages
for (i=0; i<response.data.length; i++){
document.getElementById('pageslist').innerHTML += '<span class=\"pageslistspan '+response.data[i].id+'\" onclick="showStatistics(this.classList[1])">'+response.data[i].id+' '+response.data[i].name+'</span>'+'<br>';
}
});
}
</script>

Try encapsulating your getPagesList inside document ready.
$(document).ready(function(){
getPagesList(){
...
}
});

Related

Facebook Login Popup Blocked by Browsers

I am very new to javascript, really dont understand how to do, the Facebook login still blocked by popup blocker in any browsers
I place this code to a file fbapp1.php
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'myappid', // App ID
channelUrl : '//example.com/fbapp1.php', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// this shouldn't be called directly, but instead should be initiated with a user click event
FB.login(function(response) {
if (response.authResponse) {
// document.write ('Access Token: ' + response.authResponse.accessToken);
window.location = 'https://example.com/fbapp2.php?access_token=' + response.authResponse.accessToken;
} else {
alert ('User cancelled login or did not fully authorize.');
}
});
};
// 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/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
And to open this file i am using simple html href code in another page
"Pulsa Fortune App"
But the Facebook login popup always blocked by the browsers. The code above already told this thing, but i dont know what its mean?
this shouldn't be called directly, but instead should be initiated
with a user click event
Please tell me how my code should be?
Do not call FB.login in an asynchronous callback function - fbAsyncInit is asynchronous. You have to call it on user interaction or browsers will block it for a good reason.
Example:
document.getElementById('loginBtn').addEventListener('click', function() {
//do the login
FB.login(function(response) {
if (response.authResponse) {
//user just authorized your app
document.getElementById('loginBtn').style.display = 'none';
getUserData();
}
}, {scope: 'email,public_profile', return_scopes: true});
}, false);
Source: http://www.devils-heaven.com/facebook-javascript-sdk-login/

Triggering a Facebook Message Upon a Gravity Form Submission

So far, I have the Facebook Checkbox Plugin/Widget (attached/from to Chatfuel) inside of an HTML widget in a Gravity Form. It works. Everything looks good. However, it has no effect on the actual messenger platform.
<script> window.fbMessengerPlugins = window.fbMessengerPlugins || { init : function() { FB.init({ appId: "1678638095724206", xfbml: true, version: "v2.6" }); }, callable : [] }; window.fbMessengerPlugins.callable.push( function() { var ruuid, fbPluginElements = document.querySelectorAll(".fb-messenger-checkbox[page_id='288534304507180']"); if (fbPluginElements) { for( i = 0; i < fbPluginElements.length; i++ ) { ruuid = 'cf_' + (new Array(16).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();})); fbPluginElements[i].setAttribute('user_ref', ruuid) ; fbPluginElements[i].setAttribute('origin', window.location.href); window.confirmOptIn = function() { FB.AppEvents.logEvent('MessengerCheckboxUserConfirmation', null, { app_id:"1678638095724206", page_id:"288534304507180", ref:"b64:Z2l2ZWF3YXk=", user_ref: ruuid }); }; } } }); window.fbAsyncInit = window.fbAsyncInit || function() { window.fbMessengerPlugins.callable.forEach( function( item ) { item(); } ); window.fbMessengerPlugins.init(); }; setTimeout( function() { (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')); }, 0); </script> <div class="fb-messenger-checkbox" origin="" page_id="288534304507180" messenger_app_id="1678638095724206" user_ref="" prechecked="true" allow_login="true" size="standard"></div>
After viewing the Facebook documentation (https://developers.facebook.com/docs/messenger-platform/discovery/checkbox-plugin) I stumbled upon this code:
<html>
<head>
<script>
function confirmOptIn() {
FB.AppEvents.logEvent('MessengerCheckboxUserConfirmation', null, {
'app_id':'APP_ID',
'page_id':'PAGE_ID',
'ref':'PASS_THROUGH_PARAM',
'user_ref':'UNIQUE_REF_PARAM'
});
}
</script>
</head>
<body>
<input type="button" onclick="confirmOptIn()" value="Confirm Opt-in"/>
</body>
</html>
This code is the confirmation code necessary for the message to actually fire off. When I took the code and just tested it inline on my page (rather than inside the Gravity Form) it produced a button with, as you could guess. When that button is pressed, the message fires. Keep in mind, the Gravity form with the other code is still on that same page.
Now what I need is to be able to apply this effect upon the successful submission of a Gravity Form. I'm struggling with the implementation.
I am not skilled with Javascript whatsoever. But if I had to guess, I need to put the above code for the Facebook Confirmation into the below code for it to be connected to the Gravity Forms Submission:
<script type="text/javascript">
jQuery(document).bind('gform_confirmation_loaded', function(event, formId){
// code to be trigger when confirmation page is loaded
});
</script>
https://docs.gravityforms.com/gform_confirmation_loaded/#source-code
I've also tested the following code to see if I can get it to work with just the click of the submit button, though even with this final product, I have been unable to successfully manage to trigger the Facebook message.
<script type="text/javascript">
$(document).ready(function() {
$('#gform_25 input[type=submit]').click(function () {
function confirmOptIn() {
FB.AppEvents.logEvent('MessengerCheckboxUserConfirmation', null, {
'app_id':'APP_ID',
'page_id':'PAGE_ID',
'ref':'PASS_THROUGH_PARAM',
'user_ref':'UNIQUE_REF_PARAM'
});
}
confirmOptIn();
});
});
</script>
I realize how confusing this post might be. I really hope it's not though, and that there's an answer somewhere out there. The main goal is to trigger a Facebook message after a Gravity Forms Submission. Thanks!

Uncaught ReferenceError: FB is not defined when using FB.getLoginStatus

I'm trying to check if a user has logged in using facebook and get that error in JS console. My code looks like this:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '######', // App ID
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
};
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
} else {
// the user isn't logged in to Facebook.
}
});
</script>
What could be the problem and are there any sugestions on how to fix it?
In Chrome, you'd be getting the error: Uncaught ReferenceError: FB is not defined.
I like to trigger a custom event in Facebook's initialization function, fbAsyncInit().
Then I'm not limited to doing all my FB related scripting inside of the fbAsyncInit function. I can put it anywhere, by just listening for that custom event to be fired.
window.fbAsyncInit = function() {
FB.init({
appId : '123456789',
status : true,
cookie : true,
xfbml : true
});
$(document).trigger('fbload'); // <---- THIS RIGHT HERE TRIGGERS A CUSTOM EVENT CALLED 'fbload'
};
//MEANWHILE IN $(document).ready()
$(document).on(
'fbload', // <---- HERE'S OUR CUSTOM EVENT BEING LISTENED FOR
function(){
//some code that requires the FB object
//such as...
FB.getLoginStatus(function(res){
if( res.status == "connected" ){
FB.api('/me', function(fbUser) {
console.log("Open the pod bay doors, " + fbUser.name + ".");
});
}
});
}
);
You are calling FB.getLoginStatus before the SDK is loaded and/or initialized. To wait for that, that’s what the fbAsyncInit event is for. So put the method call in there.
I used the following simple approach and it works correctly:
In the head section I load the SDK:
<script type="text/javascript" src="//connect.facebook.net/en_US/sdk.js"></script>
Then in the body of your page where your actual content is, I used this:
<script>
function statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
if (response.status === 'connected') {
testAPI();
} else if (response.status === 'not_authorized') {
FB.login(function(response) {
statusChangeCallback2(response);
}, {scope: 'public_profile,email'});
} else {
alert("not connected, not logged into facebook, we don't know");
}
}
function statusChangeCallback2(response) {
console.log('statusChangeCallback2');
console.log(response);
if (response.status === 'connected') {
testAPI();
} else if (response.status === 'not_authorized') {
console.log('still not authorized!');
} else {
alert("not connected, not logged into facebook, we don't know");
}
}
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
}
$(document).ready(function() {
FB.init({
appId : '1119999988888898981989819891',
xfbml : true,
version : 'v2.2'
});
checkLoginState();
});
</script>
Simply using script with facbook sdk directly in tag
<script type="text/javascript" src="//connect.facebook.net/en_US/all.js#xfbml=1&appId=YOUR_APP_ID" id="facebook-jssdk"></script>
We were facing the same issue, and since FB sdk was not loading (or loading with delays) this was causing problems (or breaking javascript)in some cases which were dependent upon that.
To resolve this issue, we delegated all the calls related to facebook.
We created a function like :
function callOnFBSDKLoad(callback){
if (window.isFBInitialized) {
callback();
}
else {
jQuery(document).bind('fbInitialized', callback);
}
}
Where fbInitialized is a custom event learn more about custom events here.
And window.isFBInitialized is a variable set when SDK is loaded.
callback is the method enclosing FB related events.
e.g.
var FBLogin = function(){
FB.login(...);
}
callOnFBSDKLoad(FBLogin)
PS:
Please ignore syntax and naming conventions, I am basically sharing the idea to resolve such issues.
A simpler and solid solution. Call a function when the SDK loads. I will name it triggerLoginCheck().
<script>
window.fbAsyncInit = function() {
FB.init({
//TO DO: Add your unique Facebook app ID (All numbers).
appId : '***unique_app_id***',
cookie : true,
xfbml : true,
version : 'v2.8'
});
//Call the function here
triggerLoginCheck();
FB.AppEvents.logPageView();
};
(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>
Later, anywhere, place this:
function triggerLoginCheck() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
console.log(response);
});
}
It's work fine for me. Is necessary include the Object "Log.info.bind".
var Log = { info: { bind: function(){ alert('Hi'); testAPI(); } } }

Issue with logout button

I'm trying to implement Facebook Connect login on my web page, and below you have my (poor) try so far.
If being logged out the login button is shown, as supposed.
If clicking the login button the Facebook login popup window appears, as supposed.
If loggin in the popup window disappears, the user gets logged in and the button changes to a logout button.
If clicking the logout button the user gets logged out, BUT!:
The button doesn't get changed to a login button.
Sometimes up to three popup windows (login) opens up.
The function testAPI() gets executed.
Sometimes the following error message is shown in the console: "Refused to display document because display forbidden by X-Frame-Options."
JS:
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxxxxx', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
showLogoutButton();
} else if (response.status === 'not_authorized') {
showLoginButton();
} else {
showLoginButton();
}
});
};
function showLoginButton() {
$('#FBButtonDiv').show();
$('#FBButton').html('Log in Facebook');
$('#FBButton').on('click', function(){
login();
});
}
function showLogoutButton() {
$('#FBButtonDiv').show();
$('#FBButton').html('Log out Facebook');
$('#FBButton').on('click', function(){
logout();
});
}
function login() {
FB.login(function(response) {
if (response.authResponse) {
// connected
testAPI();
showLogoutButton();
} else {
// cancelled
}
});
}
function logout() {
FB.logout(function(response) {
showLogoutButton();
});
}
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
}
(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/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
HTML:
...
<div id="FBButtonDiv"><button id="FBButton">Facebook login!</button></div>
...
CSS:
#FBButtonDiv {
display: none;
}
So, what can be wrong in my code?
Note: I know the code contains of alot of DRY but I'll do alot of refactoring when I get it to work.
Not particularly my speciality, JS/FB-API but I would guess:
function logout() {
FB.logout(function(response) {
showLogoutButton();
});
}
Should be:
function logout() {
FB.logout(function(response) {
showLoginButton();
});
}
Because after the response is recieved, the callback should be to show the login button to the now logged out user. Of course you should probably check the response similarly to login to confirm the logout was succesful.

Facebook login onClick - Javascript

I have this code on my website. The facebook login dialog is being shown when my page has loaded and not when the user has click on an anchor tag.
<script>
// Additional JS functions here
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxxx', // App ID
channelUrl : '//192.168.1.127/test/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional init code here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// connected
} else if (response.status === 'not_authorized') {
// not_authorized
login();
} else {
// not_logged_in
login();
}
});
};
function login() {
FB.login(function(response) {
if (response.authResponse) {
testAPI() ;
} else {
// cancelled
}
});
}
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
}
// 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/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
I want the FB.getLoginStatus event to be fired up whenever the user click on this:
Login
But right now it's being loaded without me doing anythings.
Suggestions?
Ok so there is a simple solution here - wrap the call to FB.getLoginStatus in another function and have your button call that function.
function doLogin(){
FB.getLoginStatus(function(response) {
...
};
}
Then you can change the onClick on your button to doLogin().
Bassicaly, what was happening here is that as soon as the Facebook SDK is loaded, it calls the window.fbAsyncInit function which contained your FB.getLoginStatus code, so as soon as the SDK was ready, the login code was being executed.

Categories