Reputation: 125
I want to pass a variable to the .done() of my ajax call that happens inside a loop. Here is my original code :
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"> </script>
</head>
<body>
<div class="list">
<div class="item" id="item1" data-user-id="1"></div>
<div class="item" id="item2" data-user-id="2"></div>
<div class="item" id="item3" data-user-id="3"></div>
<div class="item" id="item4" data-user-id="4"></div>
</div>
<script>
$('.list').children(".item").toArray().forEach(
item => {
$item = $(item)
$id = $item.data("userId")
$itemID = $item.attr('id')
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
data: { "id": $id },
}).done(res => {
console.log($itemID)
});
}
);
</script>
</body>
item4
item4
item4
item4
when I expected to see (in any order):
item1
item2
item3
item4
I found Passing variables to $.ajax().done() but neither of the 2 solutions worked :
the first one using immediately invoked function expression:
.done(
((result) => {
console.log(result)
console.log($itemID)
})(res)
);
ReferenceError: res is not defined
the second one using a custom ajax parameter :
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
data: { "id": $id },
custom: $itemID
// same results with custom: { customID: $itemID }
}).done(res => {
console.log(res)
console.log(this.cutsom)
// same output with console.log($itemID)
// console.log(this.$itemID)
});
item4
undefined
item4
undefined
item4
undefined
item4
undefined
I found other solutions that did not work either (mostly using the deprecated success
property). If I missed an obvious answer, I'm sorry, I tried my best.
Upvotes: 0
Views: 204
Reputation: 475
The best way to code something like you want, is to put your .ajax method inside a function like the following. That way, you'll define a scope to the variables.
function req($id, $itemID) {
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
data: { "id": $id },
}).done(res => {
console.log($itemID)
});
}
$('.list').children(".item").toArray().forEach(
item => {
$item = $(item)
$id = $item.data("userId")
$itemID = $item.attr('id')
req($id, $itemID);
}
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
<div class="item" id="item1" data-user-id="1"></div>
<div class="item" id="item2" data-user-id="2"></div>
<div class="item" id="item3" data-user-id="3"></div>
<div class="item" id="item4" data-user-id="4"></div>
</div>
Upvotes: 0
Reputation: 1721
Looks like a scope problem. You need to limit the scope of $item
, $id
and $itemId
to your foreach function.
var $item = $(item);
var $id = $item.data("userId");
var $itemID = $item.attr('id');
Otherwise the last call of $itemID = ...
holds your last id by the time your async ajax function is finished
Upvotes: 1