0

I'm trying to teach myself web related stuff like JavaScript and APIs after learning C/C++. This project is supposed to be a simple webpage that uses the Facebook JavaScript SDK to login with Facebook and display information from a profile. I have successfully gotten the login part done but I'm having trouble calling the FB.api() function because I need an access token. Right now I'm trying to save the access token to a var called token but it doesn't seem to be working. I am using three console.log() to debug and I've found that the last/third call returns undefined because for some reason it seems to be running first (according to the F12 dev console in Firefox). What is going on?

main.js:

function main()
{
   var token;

   FB.getLoginStatus(function getLoginStatusCallback(response)
   {
      if (response.status === "connected")
      {
         document.getElementById("loginButton").style.display = "none";
      }
      else
      {
         document.getElementById("loginButton").style.display = "all";
      }
      //THIS OUTPUTS THE TOKEN SUCCESSFULLY
      console.log(response.authResponse.accessToken);
      //THIS WORKS
      token = response.authResponse.accessToken;
      //THIS OUTPUTS THE TOKEN SUCCESSFULLY
      console.log(token);
   }, true);

   //THIS OUTPUTS UNDEFINED!
   console.log("token = " + token);

   Fb.api("/me", "get", token, function() {
      //stuff here
   });
}

How I'm initializing the FB JavaScript SDK and calling main (so I can use the FB object elsewhere).

facebook.js:

  window.fbAsyncInit = function() {
     FB.init({
        appId: 'my app id here',
        cookie: true,
        xfbml: true,
        version: 'v2.8'
     });
     FB.AppEvents.logPageView();
     //CALLING MAIN HERE
     main();
  };

  (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 = "https://connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));

The header in my HTML file (defining the SDK initialization first):

<head>
   <meta charset="utf-8" />
   <title>Profile</title>
   <link rel="stylesheet" href="style.css" />
   <script src="facebook.js"></script>
   <script src="main.js"></script>
</head>

Here is the dev console from Firefox (third console.log seems to run first for some reason, why is this happening?):

token = undefined   main.js:23:4     <-- I think it should run last but it runs first
TheTokenPrintsHere  main.js:18:7
TheTokenPrintsHere  main.js:20:7

I'm coming from C/C++ if that helps and this is my first experience with APIs and web SDKs. Thank you!

TomaszS
  • 57
  • 7

1 Answers1

0

What you're observing is a result of JavaScript executing your code Asynchronously. All of the code inside the function getLoginStatusCallback(response) block will be executed after it receives a response from FaceBook (which could take 2 seconds, 5 seconds, or 2 minutes).

JavaScript only has one thread, so the language designers made it such that this block of code will be executed only when a response is received.

If you want to force your code to execute synchronously, you can move the last 2 statements inside the first child block of main() like so:

function main()
{
   var token;

   FB.getLoginStatus(function getLoginStatusCallback(response)
   {
      if (response.status === "connected")
      {
         document.getElementById("loginButton").style.display = "none";
      }
      else
      {
         document.getElementById("loginButton").style.display = "all";
      }
      token = response.authResponse.accessToken;

      console.log("token = " + token);

      Fb.api("/me", "get", token, function() {
      // this will work now.
      });

   }, true);
}
matthewninja
  • 360
  • 5
  • 21
  • What could I do to get around this? – TomaszS Jul 31 '17 at 22:15
  • @TomaszS There are other solutions. The most common way around this is to use a [Promise](https://developers.google.com/web/fundamentals/getting-started/primers/promises) – matthewninja Jul 31 '17 at 22:16
  • I wrapped the third console.log() and Fb.api() in another function and called it from inside FB.getLoginStatus(). It works, thank you! – TomaszS Jul 31 '17 at 22:29