I am not having any issues with logging in or even calling the api, I just have an issue with getting the response outside of the api callback. I know that it runs asynchronousl
OK everyone I figured this out. It took me a long time and reading many different pages. What I said I wanted to do all deals with callbacks and closures. I will first cover the callback issue. Because the FB.api function is asynchronous you never know when it will return. You can stop Javascript or set a timer, but that is a horrible way to do this. You need a callback. In fact the FB.api is using a callback. That's what the anonymous function as the second parameter is. What I did was create another function that called fbUser and used a callback. Here is what I did:
function startThis() {
var getUser = fbUser(function(model){
console.log(model);
startapp(model);
});
};
function fbUser(callback){
FB.api('/me', function(response){
callback(response);
});
}
The startThis function is called on a positive Facebook auth response. It then calls the fbUser function which has a callback. The callback returns the callback from the FB.api function. Because startThis uses that callback with the return value being called model, the other code will not execute until the callback returns. No more undefined issues. These functions are just wrappers to get the Facebook response to my views. I may have added one too many layers of abstraction, but if you want to pass around the response this is the way.
Secondly I wanted to pass this response on to another view. For example one view loads basic info (using the response from fbUser). I now want to pass that to another view that loads photos (I know this is not best practices MVC, but by using Facebook I don't have much control over the Model). The problem I had though was I couldn't pass the original response to the next view because inside of the callback function for the FB.api call this
refers to the Window
and not the object I was in. Solution: closures. I won't explain this perfectly, but a closure is a local variable inside of a function that still has a reference inside of an anonymous function. Here is my solution which should illustrate what I am talking about:
photos: function(){
var This = this;
var apiString = '/' + this.model.id + '/photos';
FB.api(apiString, function(response){
loadPhoto(response, 1, This.model);
});
The function loadPhoto is a wrapper to load a photo view (I know backbone can help me with loading different views, but I was tackling one problem at a time). It takes the photo api call as the model, a number as an offset, and the origanl response. The first line in this function sets this to a local variable This. That allows me inside of the anonymous callback function to reference the object this was called from.
I hope this can help someone as I spent a lot of hours and a lot of testing time to find the solution to this. If you don't know about how callbacks or closures work it is hard to find the information you are looking for.