2

I've got a pair of nested AJAX request that do not behave correctly. The first gets a list of albums, and the second one gets executed for every album, giving me a list of tracks.

$.ajax({
    url:getPHPSite(),
    method:"POST",  
    data:{
        query: "SELECT id_album FROM albums;"
    },
    success: function(response){
      var albums=JSON.parse(response);
      for(var i=0; i<albums.length;i++){
          var albumID=albums[i]['id_album'];
             getTracks(function(courses) {
              //do something
            }
            }, albumID);


        }  
    }, ....//error handler and everything else

The getTracks() function actually performs the second AJAX request and returns an array of tracks with a callback

function getTracks(callback, albumID){
    $.ajax({
        url:getPHPSite(),
        method:"POST",   
        data:{
            query: "SELECT idtracks FROM tracksWHERE id_album=" + albumID + ";"
        },


        success: function(response){
            array_tracks=JSON.parse(response);   
            callback(array_tracks);
        }, //...everything else

By putting breakpoints, I discovered that the first for loop is executed separately

albumID=1
albumID=2
albumID=3
...end

and only then the getTracks() is executed.

I want the getTracks() to be executed for every iteration of albums.

Why does it happen and how can I resolve this?

riciloma
  • 1,456
  • 2
  • 16
  • 31
  • 1
    That's because JavaScript is synchronous. Read the answer for it here: http://stackoverflow.com/questions/2035645/when-is-javascript-synchronous Basically, you are creating the AJAX calls, but the loop continues afterwards before the AJAX resolves. – Hoyen Jun 01 '15 at 17:08
  • 1
    you should **never** send a mysql query wholesale via ajax!! i hope this is just a demo site because you're just inviting trouble if you execute the query without any form of input sanitation at all!! – Irvin Lim Jun 01 '15 at 17:09
  • yes this is a demo, don't worry. Thanks for the link @Hoyen – riciloma Jun 01 '15 at 17:17

1 Answers1

1

If you have problems with the Javascript asynchronous way, you could disable with the async: false flag http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings, but you will loose the javascript power.

One of the ways I think this could be done is create an array with all the resultant Ids of the first endpoint, and then do the foreach to that array, instead of embedding ajax inside ajax, but just for code maintainability.

fjcero
  • 156
  • 2
  • 14
  • Ok, I didn't want to use `async:false` because it's **deprecated**, so I managed the ajax calls using the `.done()`(the second call is execeuted inside `.done()`). About your solution, I found it really good, and implemented it into another section of the program, which isn't important anyway. So thank you very much :-) – riciloma Jun 02 '15 at 00:08
  • Awesome @RiccardoLomazzi :D – fjcero Jun 02 '15 at 00:12