3

Ok, so the problem I am having is that the jquery get() I am using does not use the variable I want it to. Here is the code and I will go into a deeper explanation.

 jQuery(document).ready(function() {

        $.ajax({
            type: "GET",
            url: "XTEST.xml",
            dataType: "xml",
            success: function(xml) {
                    console.log(xml);
                    $(xml).find('Chart').each(function(){
                        chType = $(this).find('chType').text();
                        chTitle = $(this).find('chTitle').text();
                        chSubtitle = $(this).find('chSubtitle').text();
                        yAxisTitle = $(this).find('yAxisTitle').text();
                        csv = $(this).find('csv').text();
                    });
                    $(xml).find('columns').each(function(){
                        countArray[i] = 0;
                        cNum = parseInt($(this).find('cNum').text());
                        cNumArray.push(cNum);
                        value = $(this).find('value').text();
                        valueArray.push(value);
                        vName = $(this).find('vName').text();
                        vNameArray.push(vName);
                        i++;
                    });
                },
            error: function(){
                    $('.XTEST').text('Failed to get feed');
                }
            });

        // JQuery function to process the csv data
        $.get(csv, function(data) {
           // Split the lines
            var lines = data.split('\n');

In the get(), I am attempting to give it a variable by the name of 'csv'. The intent is that the csv file name will come from a separate XML file. Although chType, chTitle, chSubtitle, etc. all work how I want them to, the 'csv' variable I created when searching through the 'Chart' section in the XML is not. The csv in the get() is shown as undeclared. Upon further investigation, it seems the get() wants to use a global variable. If you create a global variable named 'csv', it will use it. It does not appear to be a scope issue since I can use variables with data from the XML within and without the get(). It appears to be a trait of the get() line itself. Is there any solution to this, or perhaps I am missing something entirely?

AlexR
  • 33
  • 3

1 Answers1

2

It is a scope issue. The variables chType, csv are not local. If you assign a value to a variable that has not been declared, it will automatically become a global variable. So, they are automatically created as global during execution of the success callback. Before that callback they are undefined. Note that this callback is triggered asynchronously after the call $.get(). By the way, the callback inside that get is also triggered asynchronously once that request is finished. You do not know the calling order of those request callbacks.

Consider the example:

$.ajax({
           type: "GET",
           url: "XTEST.xml",
           //...
           success: function(xml) {
               console.log(xml);
               $(xml).find('Chart').each(function(){
                   chType = $(this).find('chType').text();
                   csv = $(this).find('csv').text();

                   // Automatic global variable 'csv' is defined.
                   console.log("3 csv: " + (typeof csv !== 'undefined').toString());

               });
               //...
           },
           //...
       });

// Variables 'csv' and 'chType' are not defined here.
console.log("1 csv: " + (typeof csv !== 'undefined').toString());
console.log("1 chType: " + (typeof chType !== 'undefined').toString());

// JQuery function to process the csv data
$.get('request2', function(data) {
    // Automatic global variables 'csv' and 'chType'
    // may be defined here. They are defined here only
    // if "XTEST.xml" request is already finished successfully.
    console.log("4 csv: " + (typeof csv !== 'undefined').toString());
});

console.log("2 csv: " + (typeof csv !== 'undefined').toString());

Here when the line 1 csv: is printed the variable csv is not defined. It may be defined inside of the get callback. The order of console prints: 1, 2, 3 or 4.

To avoid such confusions local variables should be declared with the var keyword.

If you want to create get requests for each csv item in the xml, you should call that .get() in the .each() callback. Beware that in that case all get callbacks will be triggered after completion of the each() loop. So, inside of all those get callbacks the values of external variables like chType will be the same corresponding to the assignment in the last loop step if the variables are global. However, if you declare them as local in the .each() callback function(){ var chType = ... } their values will correspond to each request in the .get() callbacks, see for closures explanation JavaScript closure inside loops – simple practical example

Community
  • 1
  • 1
Orest Hera
  • 6,706
  • 2
  • 21
  • 35