0

I am having a problem with using JQuery to read a text file and get the value out of the JQuery get function.

As the code below, the first console.log will display causes correctly, however when it comes out the function the second console log will not have anything.

I am wondering how to fix this?

function getCauses() {
    var causes = new Array();
    if ($("#game-type").val() == "basketball") {

        $.get('basketball.txt', function(data) {
            //split on new lines
            causes = data.split('\n');
            console.log(causes);
        });

        console.log("second: " + causes);
    }

    var c = "<option></option>";
    for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
    }
    return c;
}
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
Xin Zhao
  • 5
  • 5

2 Answers2

0

$.get() is asynchronous, as such you need to use a .then() of you want to ensure that code runs after the get is finished.

'$.get()` returns a promise, so this MDN page has some nice examples.

Edit: I'm silly and missed the fact that there's already a success in there. You could try returning the promise from $.get() to some other function and adding the stuff to the DOM there. Alternatively, just do DOM stuff in the success function directly.

Edit (again): the problem is still from a misunderstanding of how asynchronous calls work. The fact that he has a success function there does not change it to non-asynchronous like the .wait() function in C#. The browser will happily fire off the synchronous call for $.get() and then continue to the end of the function and return without waiting for the async function to get back. If OP wants things to happen when the Ajax call is complete, either everything needs to be in the success function, or his function needs to return the promise to be consumed elsewhere in his code.

So my first suggestion would look something like this which takes advantage of the underlying promise and returns that to be consumed later:

function getCauses() {
  return $.get('basketball.txt');
}

// Use function for stuff
function mainOrWhatever() {
  if ($("#game-type").val() == "basketball") {
    getCauses().done((data)=>{
      var causes = new Array();
      causes = data.split('\n');
      console.log(causes);
      var c = "<option></option>";
      for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
      }
      // Use it for whatever
      $("#dropDown").appendTo(c);
    }
  }
}

My second suggestion (and probably the better one) is to just put everything into the success call.

function getCauses() {
  if ($("#game-type").val() == "basketball") {
    $.get('basketball.txt',(data)=>{
      var causes = data.split('\n');
      console.log(causes);
      var c = "<option></option>";
      for (var i = 0; i < causes.length; i++) {
        c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
      }
      // Use it for whatever
      $("#dropDown").appendTo(c);
    });
  }
}

Of course, one can always take Bhavik's route, but I'm still not sure you want to hold up the page loading or a button click handling or whatever on a network call that could take a while. It seems like the better solution here is to change things around to make use of the async call to $.get() rather than crossing your fingers and hoping that nothing hangs while the file is loaded.

dlkulp
  • 2,204
  • 5
  • 32
  • 46
0

All Ajax calls can be done either asynchronously (with a callback function, this would be the function specified after the 'success' key) or synchronously - effectively blocking and waiting for the servers answer. To get a synchronous execution you have to specify

async: false 
function getCauses() {

  var causes = new Array();
  if ($("#game-type").val() == "basketball") {

     $.ajax({
        url:'basketball.txt',
        async: false, // try this
        success:function (data) {
          //split on new lines
          causes = data.split('\n');
          console.log(causes);
        }
     });

     console.log("second: " + causes);
   }

   var c = "<option></option>";
   for (var i = 0; i < causes.length; i++) {
      c += "<option value='" + causes[i] + "'>" + causes[i] + "</option>";
   }
   return c;
}

Try This

Bhavik Hirani
  • 1,996
  • 4
  • 28
  • 46