Search code examples
facebookember.jsfacebook-javascript-sdkember-cli

Passing function-callback in seperate SDKs (e.g. Facebook-SDK)


In a previous question I descriped my confusing about debuging JS in a proper way.

Now I need some help in handling a specific usecase.

Im trying to develop an ember-application which is able to loginto facebook using the facebook-sdk. Therefore I generated an component which places a button into the dom and react to the click. Look at this please:

import Ember from 'ember';

export default Ember.Component.extend({

  actions: {
    loginintofb: function() {
      console.log("loginintofb");
      FB.login(this.checkLoginState);
    }
  },

  checkLoginState: function() {
    console.log("checkLoginState"); // --> output | component.js:15
    //statusChangeCallback(response) //--> is not defined | also sdk.js:95 (???)
    FB.getLoginStatus(function(response) {

      // ##### HERE Ive got problems! #####
      statusChangeCallback(response); // --> is not defined | sdk.js:95

    });
  },

  statusChangeCallback: function(response) {
    console.log('statusChangeCallback');
    console.log(response);
    if (response.status === 'connected') {
      ...
    } else if (response.status === 'not_authorized') {
      ...
    } else {
      ...
    }
  }


});

The problem is the commented line: Iv have to pass an function call as a callback-handler to the facebook api. So in other words: Iam in the ember coomponent context --> going to the facebook-api --> wants to call a function back in the component.

As you may already metioned: The browser calls me, that statusChangeCallback(response); is not a function. So the place where the browser will call the function (within the Facebook-SDK I quess) is out of the scope of that function.

Also: When putting the call statusChangeCallback() right under the console.log("checkLoginState"); (see comment --> is not defined), the browser says that statusChangeCallback is not defined! The strange thing is: The terminal says, that thes reference error came from sdk.js but the line over that one (the console.log(...)) came from component.js. Ho could that be?

How can I ged rid of that? Can anybody help me please with that "scope"-based-problem?


Solution

  • You have 2 separate issues here.

    1. To refer to statusChangeCallback you need to do it off the object.
    2. The context is different in the callback.

    Consider this:

    checkLoginState: function() {
      // This will display undefined:
      console.log(statusChangeCallback);
      // this will display the function:
      console.log(this.statusChangeCallback);
    
      // This will work:
      FB.getLoginStatus(response => {
        this.statusChangeCallback(response);
      });
    },
    

    The fat arrow from means that the inner scope is inherited from the parent checkLoginState.

    We can simplify what you're trying to do though. Either:

    checkLoginState: function() {
      FB.getLoginStatus(this.statusChangeCallback);
    }
    

    Or if you want the context of statusChangeCallback to remain on the component, bind it:

    checkLoginState: function() {
      FB.getLoginStatus(this.statusChangeCallback.bind(this));
    }
    

    In an as-of-yet uncertain future of there's a bind proposal that'll simplify it to (don't use this until it's out of experimental babel):

    checkLoginState: function() {
      FB.getLoginStatus(::this.statusChangeCallback);
    }