2

I am using a loop and $.post to fill fields on my website however it is very unreliable, it works sometimes an sometimes it does not, and im not sure what the problem is if anyone has ideas what the problem could be it would be much appreciated.

for (var i = 0; i < arrayOfObjects.length; i++) {
          var object = arrayOfObjects[i];

            var option = {};
            option['username'] = object.username;
            option['COOKIE'] = $.cookie('Favorites');
            option['INITIAL'] = 'A';


            $.post("/user/favorite.do", option, function (resp) {
              var obj = $.parseJSON(resp);
              $("#AddFavorite:eq("+i+")").html(obj.txt);

}
  • 6
    rather inneficient. each of those .post calls is another http call. why not build all this data up into a single structure and then do a SINGLE ajax call to send it to the server? – Marc B Oct 23 '12 at 20:02
  • 2
    You need to close over the value of `i`. By the time the callback has been called, `i` has its final value of `arrayOfObjects.length` – zzzzBov Oct 23 '12 at 20:03
  • You should think about doing everything with a single AJAX call if possible. – Ruan Mendes Oct 23 '12 at 20:08

2 Answers2

6

As you are iterating through the array, i is incrementing. Since $.post is asynchornous, it' success callback is fireing after your loop is finished, so all of the success callbacks are triggering with i at the last index of the array. $.each would be an easy jquery way to fix it:

$.each(arrayOfObjects,function(i){
      var object = this;

        var option = {};
        option['username'] = object.username;
        option['COOKIE'] = $.cookie('Favorites');
        option['INITIAL'] = 'A';


        $.post("/user/favorite.do", option, function (resp) {
          var obj = $.parseJSON(resp);
          $("#AddFavorite:eq("+i+")").html(obj.txt);
        });

});

However this is still a very inefficient way of doing this. You should combine all these requests into one request.

A non-jquery alternative would be:

for (var i = 0; i < arrayOfObjects.length; i++) {
    (function(i){
      var object = arrayOfObjects[i];

        var option = {};
        option['username'] = object.username;
        option['COOKIE'] = $.cookie('Favorites');
        option['INITIAL'] = 'A';


        $.post("/user/favorite.do", option, function (resp) {
          var obj = $.parseJSON(resp);
          $("#AddFavorite:eq("+i+")").html(obj.txt);
        });
    })(i);
}

Also, your $.post can be simplified to:

        $.post("/user/favorite.do", option, function (resp) {
          $("#AddFavorite:eq("+i+")").html(resp.txt);
        },"json");
Kevin B
  • 94,570
  • 16
  • 163
  • 180
0

I tried the $.each solution by Kevin B but it still did not work correctly so I ended up wrapping $.post in a function, i am posting my solution as it might of help to someone with the same problem.

      fillfavorite(0); 

      function fillfavorite(i) {
      var object = arrayOfObjects[i];

        var option = {};
        option['username'] = object.username;
        option['COOKIE'] = $.cookie('Favorites');
        option['INITIAL'] = 'A';

        $.post("/user/favorite.do", option, function (resp) {
          var obj = $.parseJSON(resp);
          $("#AddFavorite:eq("+i+")").html(obj.txt);

          var g = i+1;

          i++;

          if(g<arrayOfObjects.length) { fillfavorite(i);}


        });


      }