tags:

views:

112

answers:

4

This is just freakin weird to me. So if I don't

    function BindAlbumAndPhotoData()
    {
        // Get an array of all the user's Albums
        var aAlbums = GetAllAlbums(userID, token);

        alert("aAlbums: " + aAlbums);
        if (aAlbums == null || aAlbums == "undefined")
            return;

        // Set the default albumID
        var defaultAlbumID = aAlbums[0].id;

    };

So I get an undefined error on the line var defaultAlbumID = aAlbums[0].id; if I don't uncomment the alert("aAlbums: " + aAlbums);

what the heck? If I comment out alert("aAlbums: " + aAlbums); then I get an undefined for the var defaultAlbumID = aAlbums[0].id;

This is so weird. I've been working all night to figure out why I kept getting an undefined for the aAlbum[0] and as soon as I add back an alert that I used to have above it, all is fine...makes no sense to me.

Here's the full code of GetAllAlbums:

function GetAllAlbums(userID, accessToken)
{
    var aAlbums = []; // array
    var uri = "/" + userID + "/albums?access_token=" + accessToken;

    alert("uri: " + uri);

    FB.api(uri, function (response) 
    {
        // check for a valid response
        if (!response || response.error) 
        {
            alert("error occured");
            return;
        }

        for (var i = 0, l = response.data.length; i < l; i++) 
        {
            alert("Album #: " + i + "\r\n" +
                  "response.data[i].id: " + response.data[i].id + "\r\n" +
                  "response.data[i].name: " + response.data[i].name + "\r\n" +
                  "response.data[i].count: " + response.data[i].count + "\r\n" +
                  "response.data[i].link: " + response.data[i].link
                  );

            aAlbums[i] = new Album(
                                                    response.data[i].id,
                                                    response.data[i].name,
                                                    response.data[i].count,
                                                    response.data[i].link
                                                   );

            alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
        }
    });

    return aAlbums;
}

so I'm not returning the array until I hit the callback of the FB.api async call so I don't see how my defaultAlbumID = aAlbums[0].id; line of code is executing before I have a valid array of data back. When I put in the alert, ovbvioulsly it's delaying before it hits my line defaultAlbumID = aAlbums[0].id; causing it to I guess luckily have data beacuse the async FB.api call is done but again I don't see how that's even possible to have an issue like this when I'm waiting for the call before proceeding on and returning the array to aAlbums in my BindAlbumAndPhotoData() method.

UPDATE #3

            function BindAlbumAndPhotoData()
            {
                GetAllAlbums(userID, accessToken, function (aAlbums) 
                {
                    alert("we're back and should have data");

                    if (aAlbums === null || aAlbums === undefined) {
                        alert("array is empty");
                        return false;
                    }

                    var defaultAlbumID = aAlbums[0].id;

                    // Set the default albumID
                    var defaultAlbumID = aAlbums[0].id;

                    // Bind the album dropdown
                    alert(" defaultAlbumID: " + defaultAlbumID);

                 });
            };


function GetAllAlbums(userID, accessToken, callbackFunctionSuccess)
{
    var aAlbums = []; // array
    var uri = "/" + userID + "/albums?access_token=" + accessToken;

    FB.api(uri, function (response) 
    {
        // check for a valid response
        if (!response || response.error) 
        {
            alert("error occured");
            return;
        }

        for (var i = 0, l = response.data.length; i < l; i++) 
        {
            alert("Album #: " + i + "\r\n" +
                  "response.data[i].id: " + response.data[i].id + "\r\n" +
                  "response.data[i].name: " + response.data[i].name + "\r\n" +
                  "response.data[i].count: " + response.data[i].count + "\r\n" +
                  "response.data[i].link: " + response.data[i].link
                  );

            aAlbums[i] = new Album(
                                                    response.data[i].id,
                                                    response.data[i].name,
                                                    response.data[i].count,
                                                    response.data[i].link
                                                   );

            alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
        }

        // pass the array back to the callback function sent as a param to the GetAllAlbums method here
        callbackFunctionSuccess(aAlbums); 
    });
}

It's not hitting my alert in the callback. I must still be doing something wrong here.

UPDATE #4 - for some reason it's not hitting my FB.api callback now.

function GetAllAlbums(userID, accessToken, callbackFunctionSuccess)
{
    var aAlbums = []; // array
    var uri = "/" + userID + "/albums?access_token=" + accessToken;

    alert("uri: " + uri);

    FB.api(uri, function (response) 
    {
        // check for a valid response
        if (!response || response.error) 
        {
            alert("error occured");
            return;
        }

        for (var i = 0, l = response.data.length; i < l; i++) {
            alert("Album #: " + i + "\r\n" +
                  "response.data[i].id: " + response.data[i].id + "\r\n" +
                  "response.data[i].name: " + response.data[i].name + "\r\n" +
                  "response.data[i].count: " + response.data[i].count + "\r\n" +
                  "response.data[i].link: " + response.data[i].link
                  );

            aAlbums[i] = new Album(
                                                    response.data[i].id,
                                                    response.data[i].name,
                                                    response.data[i].count,
                                                    response.data[i].link
                                                   );

            alert("aAlbums[" + i + "].id : " + aAlbums[i].id);
        }

        alert("about to pass back the array to the callback function");
        // pass the array back to the callback function sent as a param to the GetAllAlbums method here
        callbackFunctionSuccess(aAlbums);
    });
}
A: 

Try modifying your condition like this:

  if (typeof aAlbums == 'undefined')
      return;

Also make sure that aAlbums has values and is an array:

alert(aAlbums.length);

Or:

for(var i = 0; i < aAlbums.length; i++)
{
  alert(aAlbums[i].id);
}
Sarfraz
well I get a length of zero even though I know the array has values in it...weird.
CoffeeAddict
if (typeof aAlbums == 'undefined') return; doesn't work or make any difference..just tested.
CoffeeAddict
@coffeeaddict: If its length is 0 then it is not filled with data, not an array. Make sure that function `GetAllAlbums` works fine.
Sarfraz
it will return zero because you are waiting for the `ajax` data when that script line get executed... too slow for the computer, too fast for your eye... that's why you are seeing the data but JS says it's undefined...
Reigel
so...Zane is saying not to use quotes....is that because he's using the === ?
CoffeeAddict
getalbums is working only if I put that alert in there meaning it gives it a chance to run before it hits var defaultAlbumID = aAlbums[0].id; I think....
CoffeeAddict
please see my update to the main thread..added the GetAllAlbums function to show you how that works.
CoffeeAddict
No, I'm saying not to use quotes because undefined is a reserved property in Javascript already. If you were to use quotes, then you're assuming that in your GetAllAlbums function, you actually assigned the string "undefined" to it's return; which you didn't.The triple equals sign is just a stricter comparison.
Zane Edward Dockery
+4  A: 
function BindAlbumAndPhotoData()
{
    // Get an array of all the user's Albums
    GetAllAlbums(userID, token, function(aAlbums){

        // Set the default albumID
        var defaultAlbumID = aAlbums[0].id;

    });

};

and then in the GetAllAlbums function call the success function when you have the data back

//*** AFTER THE BREAK *//

In response to the updated question: The FB API is mostly asynchronous, and will keep executing other code while it waits. So using your code, all I have done is passed in the function, and then call the function you've passed it at the end

function GetAllAlbums(userID, accessToken, funcSuccess)
{
    var aAlbums = []; // array
    var uri = "/" + userID + "/albums?access_token=" + accessToken;

alert("uri: " + uri);

FB.api(uri, function (response) 
{
    // check for a valid response
    if (!response || response.error) 
    {
        alert("error occured");
        return;
    }

    for (var i = 0, l = response.data.length; i < l; i++) 
    {
        alert("Album #: " + i + "\r\n" +
              "response.data[i].id: " + response.data[i].id + "\r\n" +
              "response.data[i].name: " + response.data[i].name + "\r\n" +
              "response.data[i].count: " + response.data[i].count + "\r\n" +
              "response.data[i].link: " + response.data[i].link
              );

        aAlbums[i] = new Album(
                                                response.data[i].id,
                                                response.data[i].name,
                                                response.data[i].count,
                                                response.data[i].link
                                               );

        alert("aAlbums[" + i + "].id : " + aAlbums[i].id);



    }

    funcSuccess(aAlbums);
});

}

jamie-wilson
I'm using the Facebook SDK to make JS ajax calls.
CoffeeAddict
Then instead of the jquery bit in the function there, from the FB examples i've seen you'd want something like ajax.ondone = function(data) { funcSuccess(data); };The only reason I wrap it inside another function is that it leaves you the room to do some quality control (if data!=null) etc
jamie-wilson
jamie, thanks. Check out my update above to the thread...see my function there for GetAllAlbums.
CoffeeAddict
so now that I've showed you how my GetAllAlbums() is working, I don't now if your example makes sense using GetAllAlbums(userID, token, function(aAlbums){... because I'm using the callback of FB.api to wait for the response. I don't understand your syntax I guess either with the funcSuccess anyway in how you added it as a param there.
CoffeeAddict
but what is url: "thisurl", for when the FB.api is sending the request, not a jQuery ajax function?
CoffeeAddict
"So using your code, all I have done is passed in the function" what function do you mean by the function...I'm lost. So you passed in what to the GetAllAlbums?
CoffeeAddict
so basically you added a callback to GetAllAlbums which will be called once the funcSuccess(aAlbums); is returned? I guess I don't get callbacks in terms of how they talk to each other here.
CoffeeAddict
so function (aAlbums) in BindAlbumAndPhotoData() is called by funcSuccess(aAlbums); at the end of my GetAllAlbums and sends back the array...I think I got it. I don't even think I need the jQuery. The FB.api sits and waits for the data in its own callback via the response object.
CoffeeAddict
Sorry, I removed the jquery reference, it was a double up and completely unnecessary. And yup your last comment was completely right :) - I find this method of callbacks really handy, as it means your ajax calls can be more generic
jamie-wilson
ok I tried this, I think I get it...see update. I'm not getting the alert to fire though on the callback.
CoffeeAddict
Just commented on the original post, don't 'return' the function, just execute it :)
jamie-wilson
yea, just saw that. But still not hitting my callback for some reason..let me do some more testing. For some reson now it's not hitting the callback for FB.api(uri, function (response) { });
CoffeeAddict
That is strange, well if you don't get somewhere soon post your code somewhere online so I can have a play
jamie-wilson
awesome it's working THANK YOU SO MUCH. I just learned truly how callbacks work, not just relying on some third party API. It's really essential to know how to do this with plain JS.
CoffeeAddict
+1  A: 

Try three equals signs instead of two, and also... return false rather than nothing at all.

if (aAlbums === null || aAlbums === undefined)
            return false;

Also, undefined doesn't need to be in quotes, otherwise, it's just considered a string with a value of "undefined"

On an added note, it's probably better to ALSO check if aAlbums is actually an array before you decide to return a key from it.

if (   aAlbums === null 
    || aAlbums === undefined
    || (typeof(aAlbums)=='object'&& !(aAlbums instanceof Array))
    } return false;
Zane Edward Dockery
As you put it, it's `undefined` not `"undefined"`
George Marian
this did not make a difference: if ( aAlbums === null || aAlbums === undefined || (typeof(aAlbums)=='object'
CoffeeAddict
please see my update to the main thread..added the GetAllAlbums function to show you how that works.
CoffeeAddict
+1  A: 

Is your function GetAllAlbums() doing some HTTP requests? If so then you need to either make that call synchronous or you need to put your code into a function and pass that as a callback to the Ajax request.

Jesse Dhillon
yes doing that already in the callback of FB.api. See my updated post.
CoffeeAddict