Angel ofDemons Angel ofDemons - 6 months ago 43
PHP Question

Ajax call in for loop returns same value only once

I know it has been asked multiple times but I cant seem to figure the

closure
stuff out, atleast I can't seem to apply it to my own code.

here I create a for loop based on the
.choice
class.

<label class="choice" data-id="1"><input type="radio" name="group1" value="een">een</label>
<label class="choice" data-id="2"><input type="radio" name="group1" value="twee">twee</label>
<label class="choice" data-id="3"><input type="radio" name="group1" value="drie">drie</label>
<label class="choice" data-id="4"><input type="radio" name="group1" value="vier">vier</label>

$(document).ready(function(){
for (var i = $('.choice').length - 1; i >= 0; i--) {
var element = $('.choice')[i];
var choiceID = $(element).data('id');
var value = $(element).find('input').val();

$.ajax({
method: "POST",
url: 'api.php',
data: {
choiceID: choiceID,
value: value
},
success: function(res) {

if(value == JSON.parse(res).value) {
console.log(JSON.parse(res).value);
console.log(JSON.parse(res).count);
if(JSON.parse(res).count > 0){
$(element).addClass('full');
}
} else {
// console.log("FAILED " + JSON.parse(res).value);
// console.log("FAILED " + JSON.parse(res).count);
}
}
});

}


});

Then on the
api.php
file I call multiple query's

$choiceID = $_POST["choiceID"];
$value = $_POST["value"];
$kolom = "choice_" . $choiceID;

$counter = 0;
$array = [];

$query = "SELECT choice_1 FROM resultaten WHERE choice_1 = '".$value."'";
$getCount = $db->query($query);
$getCount->execute(array("value"=>$value));
$results = $getCount->fetchAll(PDO::FETCH_ASSOC);


more queries and for loops

ajax succes callback
echo json_encode(array("value" => $value, "count"=> $counter, "ID" => $choiceID));


for the first
choice
class with a
data-id
of
1
it works and applies the class
full


but when i console.log the
value
and
count
it returns
een 1

and in the console
VM1982:1 Uncaught SyntaxError: Unexpected token < in JSON at position 1
Probably something to do with the
data-id
of
1/2/3/4
etc. (I think it should all be
one
) but when I put them all to
1
it just works for the first one. Same as when I use
1/2/3/4
as
data-id
. Also it is kinda weird that it with some results returns
<br />
<b>Notice</b>: Undefined index: choice_2 in <b>C:\xampp\htdocs\form\api.php</b> on line <b>47</b><br />
{"value":"use your apple","count":2,"ID":"2"}
It says it has a
count
of 2 and in the ajax it says when
count
= above 0 it sould give the class
full
but it gives the
undefined index: choice_2
instead


I think this causes the main problem


And when I
console.log
value
inside of the
succes
function it returns
een
which is the
first
value of the
choice
classes.

while when I
console.log
the
value
below the
value
variable it returns all of the variables.

Answer

The problem is element, choiceID, and value are all changing synchronously. By the time the AJAX response gets back, the values are different from when each request began.

This is probably the easiest change you code make

for (var i = $('.choice').length - 1; i >= 0; i--) {
  (function() {
    var element = $('.choice')[i];
    var choiceID = $(element).data('id');
    var value = $(element).find('input').val();

    // rest of your loop code here...
  })();
}

Now, each time the loop runs, element, choiceID, and value will have their values properly bound to the closure.


You're not using the i iterator, otherwise it's common to see that passed into the Immediately Invoked Function Expression (IIFE).

for (var i = $('.choice').length - 1; i >= 0; i--) {
  (function(i) {
    // your loop code here
  })(i);
}

Anyway, this is all just a symptom of bad code design in general. If you used functions to describe the separate operations of your code (instead of one giant blob inside a for loop), you would've never had this issue to begin with.