So I am currently working with the facebook javascript sdk. I seem to be out of scope every time I make an api call, and could really use some help here....
function ExampleClass(nameValue) {
//private properties
var name;
//etc.
//public class methods
this.setName = function() {
var callback = (function(name) {
return function(response) {
name = response.last_name;
console.log("this is the name " + name);
}
})(name);
FB.api('/me', {
fields: 'last_name'
}, callback);
//check if name has been set - it is still the name handed to the constructor
console.log(name);
};
this.getName = function() {
return name;
};
}
var demo = new ExampleClass("initial value");
demo.setName();
console.log(demo.getName());
//-------------------------------------------------------------------------
So I followed along with another question on scope here which I thought seemed to be my problem, but the return the function within the callback did nothing for me. I am at a complete lose here would appreciate any insight you could offer.
Thanks :)
If all you want to do with .getName()
is get the name into the private variable name
, then I think you can just do this:
function ExampleClass(nameValue) {
//private properties
var name;
//etc.
//public class methods
this.setName = function() {
FB.api('/me', {fields: 'last_name'}, function(response) {
name = response.last_name;
//check if name has been set - it is still the name handed to the constructor
console.log(name);
});
};
this.getName = function() {
return name;
};
}
Issues in your previous implementation:
You were redefining name
which hid access to your private property by the same name so it couldn't be used in some contexts.
You massively overcomplicated the api callback with an IIFE returning a function. A simple callback is all that is needed here.
You were checking the value of name
outside of the callback so that check wasn't waiting for the actual new value to be set. FB callbacks are asynchronous. That means they happen at some indeterminate time in the future and your other code has already run. If you want to use the result of a callback, you have to use it IN the actual callback or in a function that you call from the callback.
Issues still present:
You're providing no means of notification for when setName()
is actually done.
You've covered up any chance at error handling outside of ExampleClass
(e.g. it just ignores errors and doesn't propagate anything outside).
If you wanted to know when setName was actually done, the usual way to do that in Javascript is to offer an (optional) callback that can be used:
function ExampleClass(nameValue) {
//private properties
var name;
//etc.
//public class methods
this.retrieveName = function(callback) {
FB.api('/me', {fields: 'last_name'}, function(response) {
name = response.last_name;
//check if name has been set - it is still the name handed to the constructor
console.log(name);
if (callback) {
// Fixme: also should probably communicate FB API errors here
callback(name);
}
});
};
this.getName = function() {
return name;
};
}
var x = new ExampleClass("ted");
x.retrieveName(function(name) {
// verify both of these are the same now
console.log(name);
console.log(x.getName());
});