0

In the code below, I assign a value to a variable from JSON with this var tag = data[j]['text']; and I output it with this console.log(tag); (for testing) which works.

I try to push the values into an array with tags.push(tag); but it WILL NOT WORK!

Why won't these values go into the array? I am just trying to get the contents of tag into an array...

function GetAvailableTags() {
            var url = '/TextCodes/TextCodes?key=';
            var tagGroups = [];
            $('.ui-autocomplete-input').each(function () {
                var key = $(this).attr('id');
                var tags = [];
                //console.log(key);
                $.getJSON(url + key, function (data) {
                    for (var j = 0, len = data.length; j < len; j++) {
                        var tag = data[j]['text'];
                        console.log(tag);
                        tags.push(tag);
                    }
                });
                console.log(tags.length);
                for (var k = 0, len = tags.length; k < len; k++) {
                    console.log(tags[k]);
                }
            });
        }

Thanks for your help.

user1477388
  • 20,790
  • 32
  • 144
  • 264
  • 2
    You must defer using the response from the JSON call until the call has actually completed; the JavaScript program doesn't wait for the response. Use Deferreds or the success handler, and put your code in there instead. See http://learn.jquery.com/ajax/ – Matt Mar 17 '13 at 16:35
  • Ah not the scope sorry, missed a bracket... – Maresh Mar 17 '13 at 16:36
  • 1
    You are logging the array before the ajax response fills it. See [How to return the response from an AJAX call from a function?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call-from-a-function) – Bergi Mar 17 '13 at 16:36
  • Am I not simply doing what is being done successfully here http://stackoverflow.com/a/5273921/1477388 ? Why won't it work for me? – user1477388 Mar 17 '13 at 17:40

2 Answers2

2

Because $.getJSON is an asynchronous function. It means that your code

console.log(tags.length);
for (var k = 0, len = tags.length; k < len; k++) {
    console.log(tags[k]);
}

will be executed before the $.getJSON callback function :

function () {
    var key = $(this).attr('id');
    var tags = [];
    //console.log(key);
    $.getJSON(url + key, function (data) {
        for (var j = 0, len = data.length; j < len; j++) {
            var tag = data[j]['text'];
            console.log(tag);
            tags.push(tag);
        }
    }

It is why your variable seems to be empty when look into in your code above, but how it is possible that the data are printed with console.log(tag); in the callback function.

Update

Here is an example of using $.ajax method instead of $.getJSON to specify that the data must be retrieved synchronously using the parameter asynch : false

By that way, the server call response (success callback) is mandatory to continue the process. The disadvantage of this non-standard way is that your web page could be freezed waiting the server response. It is not the best elegant way to do that, but sometimes it is useful.

function GetAvailableTags() {
    var url = '/TextCodes/TextCodes?key=';
    var tagGroups = [];
    $('.ui-autocomplete-input').each(function () {
        var key = $(this).attr('id');
        var tags = [];
        //console.log(key);
        $.ajax({
            url: url + key,
            type: 'POST',
            asynch: false,//specify to stop JS execution waiting the server response
            success: function (data) {
                for (var j = 0, len = data.length; j < len; j++) {
                    var tag = data[j]['text'];
                    console.log(tag);
                    tags.push(tag);
                }
            },
            error : function(jqXHR, textStatus, errorThrown) {
                alert('an error occurred!');
            }
        });
        console.log(tags.length);
        for (var k = 0, len = tags.length; k < len; k++) {
            console.log(tags[k]);
        }
    });
}
sdespont
  • 13,915
  • 9
  • 56
  • 97
  • How, then, can I get the json data into an array? – user1477388 Mar 17 '13 at 16:46
  • You are pushing the value into the array. You are just tryin to display it before it gets there. You may consider using $.ajax and setting async=false rather than the getJSON shorthand: see http://api.jquery.com/jQuery.getJSON/ – ron tornambe Mar 17 '13 at 16:48
  • Your data are in the array, but only when the callback has been executed. Add your logic into the callback to use the array data like form element value updating or whatever you want to do. You could also call a function to execute at then end of the callback. – sdespont Mar 17 '13 at 16:49
  • Where is the callback function for the `$.getJSON` method? On http://api.jquery.com/jQuery.getJSON/ they just seem to be doing what I am doing, basically. They loop through with `$.each` and push to array... – user1477388 Mar 17 '13 at 17:26
  • The callback is the function defined as second parameter of the $.getJSON method. This function is called when the server replies the data. You are already using the callback, it is where you are creating the array – sdespont Mar 17 '13 at 19:29
  • Thank you for the update, but when I run `console.log(tags[k]);` it outputs `0` (zero). It seems I am at the same place I was before. `console.log(tag);` works fine, just as before, but when the data is added to the array, it won't seem to be read... Here is the actual datasource I am using http://tinyurl.com/cmpf7d9 (ex. /TextCodes/TextCodes?key=taxes). The keys I am passing are `#propertyInfo, #legalDesc, #taxes, #additionalTaxes, #mortgagesLiensCourt, #additionalMatters` – user1477388 Mar 17 '13 at 20:27
0

My solution is kind of long and stupid, but it works. Now, I can access the variables like an array textCodes['taxes']. sdespont's async note helped, too.

    var textCodes = GenerateTextCodes();
    console.log(textCodes);

    function GenerateTextCodes() {
        var arr = [];
        $('.ui-autocomplete-input').each(function () {
            var id = $(this).attr('id');
            arr[id] = GetAvailableTags(id);
        });
        //console.log(arr['taxes']);
        return arr;
    }

    // get all autocomplete element IDs and put them into an array
    function GetAvailableTags(key) {
        var url = '/TextCodes/TextCodes?key=';
        var tags = [];
        $.ajax({
            url: url + key,
            type: 'GET',
            async: false,
            success: function (data) {
                //console.log(data[0].text);
                //console.log(data.length);
                for (var i = 0; i < data.length; i++) {
                    //console.log(data[i].text);
                    tags.push(data[i].text);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert('an error occurred!');
            }
        });
        //console.log(tags);
        return tags;
    }
user1477388
  • 20,790
  • 32
  • 144
  • 264