4

I am sure I am doing this all kinds of wrong, but I have the following function returning 'undefined' in the console even though it can console.log() the wanted values from the same place in the function as commented in the code.

var tags = [4, 5];
console.log(getTagNames(tags)); // 'undefined'

function getTagNames(tagArray) {  

    $.getJSON('js/tags.json', function(data) {
        for (var i in tagArray) {
            tagArray[i] = tagArray[i].toString();
            var val = tagArray[i];

            for (var t in data) {
                var tag = data[t];
                var tagName = tag.alias;
                var tagId = tag.id;
                if (val === tagId) {
                    tagArray[i] = tagName;
                }
            };
        }
        console.log(tagArray); // output ["foo", "bar"] 
        return tagArray;
    });
}

The other odd thing is that, after running this code in the browser, I can type "tags" into the browser console and it gives me the correct result ["foo", "bar"]. However when I try using the tags variable (i.e.: text value for an element and such), it doesn't work... What Gives? JavaScript isn't my first language so I am a little confused of exactly how it behaves. I just don't understand.

I have read almost all of the "Questions that may already have my answer", but the answers supplied where those that I couldn't figure out how to apply to my function.

NOTE:

  1. The JSON is from the Joomla(3.1) tags table.
  2. I am able to retrieve the data.
  3. The val === tagId conditional is working correctly.
  4. I like popcorn.
jremydeaton
  • 133
  • 1
  • 3
  • 13
  • 1
    `getTagNames` **doesn't have** a `return` statement. The only function with a `return` statement in your question is the anonymous function you pass to `getJSON`. – Quentin Jun 28 '13 at 19:15

2 Answers2

9

The call to getJSON calls your callback function asynchronously.

If you need the function getTagNames and call it many places in your code you could make changes to make it take a callback function itself:

function getTagNames(tagArray, cb) {  

    $.getJSON('js/tags.json', function(data) {
        for (var i in tagArray) {
            tagArray[i] = tagArray[i].toString();
            var val = tagArray[i];

            for (var t in data) {
                var tag = data[t];
                var tagName = tag.alias;
                var tagId = tag.id;
                if (val === tagId) {
                    tagArray[i] = tagName;
                }
            };
        }
        console.log(tagArray); // output ["foo", "bar"] 
        cb(tagArray);
    });
}

and then make calls to it like this:

getTagNames(tags, function(tagArray) {
    // do something with tagArray
});
Michael Banzon
  • 4,879
  • 1
  • 26
  • 28
  • I think its the "callback" function that I don't get when I need to make calls to the getTagNames function. Like what does the parameter, tagArray represent here. And what would I want to do with it. I guess I am used too php in just returning value. – jremydeaton Jun 28 '13 at 20:32
  • 1
    tagArray is copied (like most of the code) from your original. So tagArray is getting populated by calling getTagNames. The second parameter you pass is a function that handles the "return value" when the call to getTagNames is "finished". – Michael Banzon Jun 28 '13 at 22:35
2

Statement return tagArray; returns result of success handler of getJSON which, first, does not expect any return value, and second, happens asynchronously - way after your getTagNames finished executing.

Igor
  • 15,833
  • 1
  • 27
  • 32
  • 1
    That's pretty much the the answer I got from the other questions that I looked over, and I only half understand how it works. However I can't seem to find any reference material that dumbs-it-down for my current comprehension of the whole concept. Still reading over some material so I can hit that "AH HA" moment. Any place anyone can direct me (preferably tutorial based) is greatly appreciated. – jremydeaton Jun 28 '13 at 20:26