0

I'm trying to use bind to access external variables with ajax requests. I've replicated my problem in the code snippet below.

My ajax request is within a for loop, and I'm trying to bind eid and pid to the success function such that I can access their value at the time of the request. However, it seems that this has messed up data and status, because data is 'myPid' and status is an object with my returned data, although eid and pid seem to have displayed correctly.

The jQuery .ajax specification says that the arguments to the function are result, status, and xhr in that order, and this seems to be how it works before I add the step to bind eid and pid.

Am I missing something? Why does my returned data get bound to status instead?

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>

$(document).ready(function(){
    $("button").click(function(){
      var pid = 'myPid';
      var eids = [888, 999];
      for(var ind in eids) {
        let eid = eids[ind];
        $.ajax({
          url: "https://reqres.in/api/users?page=2", async: false,
          success: function(data, status) { 
            console.log("data:"+data);
            console.log("status:"+status);
            console.log("eid:"+eid);
            console.log("pid:"+pid);
          }.bind(eid, pid), 
          error: function(a, b, err) {
            console.log(err);
          }
        });
      }
    });
});
</script>
</head>
<body>

<div><h2>Let AJAX change this text</h2></div>

<button>Change Content</button>

</body>
</html>
Giselle Serate
  • 184
  • 2
  • 12
  • 1
    `bind()` is used to assign a new `this` context to a function. Further arguments to `bind()` are put before the passed ones. If you want to create individual variables for each iteration of a for loop, simply declare them using `let` instead of `var`. Fiddle: https://jsfiddle.net/khrismuc/czd21wmv/ –  Jul 05 '18 at 16:27
  • I've changed the `var` to a `let`, but that doesn't seem to make a difference (and essentially what's happening in my original code because I was using an object and not an array). What I've found that seems to work is adding a dummy parameter to the beginning of the success function, e.g. `success: function(dummy, data, status)`. Is this how I'm supposed to handle it? – Giselle Serate Jul 05 '18 at 16:35
  • 1
    **Never ever** use `async:false`! It is a horrible practice and is deprecated by browser vendors. You should be seeing warnings in browser console regarding that – charlietfl Jul 05 '18 at 16:38
  • A simple fix is to change the `for()` to `$.each(eids, function(index, eid){...`. Will create a closure – charlietfl Jul 05 '18 at 16:41
  • I used `let` on the iterator variable instead of `var`, took out `bind()`, and this worked to fix everything. Thanks so much @ChrisG! (Also thanks @charlietfl; didn't get to trying your answer, but appreciate the option!) – Giselle Serate Jul 05 '18 at 16:56

0 Answers0