0

I am trying to build a jquery each loop with an ajax call in it, but for some reason it doesn't stop executing and thus loops all of my code.

What am I doing wrong here?

The each loop:

$.each(JSEFileNames, function(key, value){
    $.ajax({ url: "/"+key,
      success: function(r){
        $(JSEPlaceholder).html(r);
        JSEFileNames[key] = $(JSEPlaceholder).text().toString().replace(/(\r\n|\n|\r)/gm,"") + $(JSEPlaceholder).children().text().toString().replace(/(\r\n|\n|\r)/gm,"");
        $(JSEPlaceholder).empty();
        return;
      }
    });
  });

JSEFileNames contains something similar to

JSEFileNames= {
"index.php": "", 
"something.txt": ""
}

and JSEPlaceholder is just a string containing "#searchBox".

This is the full code: https://jsbin.com/kifisameto/edit?html,js,output

Gerrit Luimstra
  • 522
  • 6
  • 23

1 Answers1

0

Note that the return is pointless since it is the last line of the function already. It will only exit this function, but the $.each will keep executing since it is contained in another function.

This is what happens if you break down your code:

$.each(JSEFileNames, ajaxFunction);

function ajaxFunction(key, value){
    $.ajax({ url: "/"+key, success: successFunction });
}

function successFunction(r) {
    $(JSEPlaceholder).html(r);
    JSEFileNames[key] = $(JSEPlaceholder).text().toString().replace(/(\r\n|\n|\r)/gm,"") + $(JSEPlaceholder).children().text().toString().replace(/(\r\n|\n|\r)/gm,"");
    $(JSEPlaceholder).empty();
    return;
}

Here you can see that the return is not doing what you want it to do. You will need to do a return false inside the ajaxFunction call for it to stop. This is an example of how you can do it:

$.each(JSEFileNames, function(key, value){
    cont = true;
    $.ajax({ url: "/"+key, async: false,
      success: function(r){
        $(JSEPlaceholder).html(r);
        JSEFileNames[key] = $(JSEPlaceholder).text().toString().replace(/(\r\n|\n|\r)/gm,"") + $(JSEPlaceholder).children().text().toString().replace(/(\r\n|\n|\r)/gm,"");
        $(JSEPlaceholder).empty();
        cont = false;
      }
    });
    return cont;
});

Here what happens is that a return value with value evaluating to false will stop the jQuery loop; if value is true, the loop will keep running. See here for the official documentation.

Notice that I added async: false; indeed, $.ajax is an asynchronous function, and it will return before cont can be modified. The underlying call will only be treated later, once the request succeeds or fails. One way around that is to make the request synchronous, but it will prevent the rest of your code from executing in the meantime. This is probably what you're looking for here, since you're visibly performing a search over a number of pages, and you don't want all pages to be searched at once, but rather check them one after the other.

pie3636
  • 795
  • 17
  • 31
  • Sorry, it is still not working. Good thinking anyway. – Gerrit Luimstra Jul 30 '16 at 16:59
  • Can you expand on this? What is happening exactly, and what is the desired output? – pie3636 Jul 30 '16 at 17:00
  • https://jsbin.com/kifisameto/edit?html,js,output This may help a little. – Gerrit Luimstra Jul 30 '16 at 17:04
  • Okay, what happens here is that the `$.ajax` function returns before issuing the actual call, since it is an asynchronous function. I suggest checking [this answer](http://stackoverflow.com/a/13487573/2700737) for more information. One thing you can do is add `async: false` within your `$.ajax` parameters. However, be aware that it will freeze your code while the call is being executed. I have changed my answer to reflect that. – pie3636 Jul 30 '16 at 17:09
  • But I cannot do that. Because I have to loop through the object AFTER the each is completed and thus the ajax call(s). How can this be accomplished? – Gerrit Luimstra Jul 30 '16 at 17:12
  • With async:false this is still just looping. – Gerrit Luimstra Jul 30 '16 at 17:13
  • What are you trying to do specifically? Perform all the requests, and then search them? Why do you want it to stop executing then, instead of "running the whole code"? – pie3636 Jul 30 '16 at 17:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118707/discussion-between-gerrit-luimstra-and-pie3636). – Gerrit Luimstra Jul 30 '16 at 17:19