1

I have one callback function

function QueryKeyword(keyword, site, callback) {
  var querykeyword = keyword;
  var website = site;

  $.ajax({
    url: "http://www.test.com",
    jsonp: "jsonp",
    dataType: "jsonp",
    data: {
      Query: querykeyword
    },
    success: callback
  });
}

I am calling this function with in for loop like this :

for (i = 0; i < questionTerm.length; i++) {
  for (j = 0; j < site.length; j++) {
    var searchTerm = questionTerm[i] + ' ' + $('#search').val();

    QueryKeyword(searchTerm, site[j], function(reslt) {
      // I need to get j variable value here
      console.log(j);
    });

  }

}

Now I need to get "j" variable value in function see I console the j variable value but it does not get the j variable value.

Would you please let me know how I can fetch the value in this.

Thanks in advance

Saeed
  • 5,413
  • 3
  • 26
  • 40
Dhaval
  • 89
  • 2
  • 11
  • What exactly means for you "It doesnt get the j variable value". Is it undefined? Its a wrong value? Is it null? – Cristian S. May 22 '18 at 14:56
  • You should declare your variables properly. In this case, declaring them with `let` will fix the problem because `j` will then be block-scoped, and each callback function will close over its own, unique `j`. –  May 22 '18 at 14:56
  • 1
    Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Taplar May 22 '18 at 15:01

2 Answers2

4

The problem is, that at the moment of your callback, j was reassigned multiple times to something different.

There are a few options you could do.

  1. call your callback with the params you need

function QueryKeyword(keyword, site, index, callback) {
  // ...
  $.ajax(
      success: function(result) {
          // call the callback with a second param (the index j)
          callback(result, index);  
      }
  )
}

QueryKeyword(searchTerm, site[j], j, function(reslt, param) {
   // param is j
   console.log(result, param);
});
  1. save the var in a closure

(function() {
    var value = j;
    ...
})();
  1. use forEach

questionTerm.forEach((term, i) => {
    site.forEach((s, j) => {
        // we are in a closure, 
        // j will be correct here.
        QueryKeyword(term, s, function(reslt) {
          // j is still correct here
          console.log(j);
        });
    })
});
  1. if you use es6, you could use let keyword. Here is some good explanation, how it works when using for loops

for(let i = 0; i < 10; i++) {
 console.log(i);
 setTimeout(function() {
   console.log('The number is ' + i);
 },1000);
}
Luke
  • 8,235
  • 3
  • 22
  • 36
  • When I use FOREACH then get "J" value but not true because when I call the function then make ajax call so each executes faster so return value like 0,3. But i need value like 0,1,2,3 like this. – Dhaval May 22 '18 at 16:18
  • so you need the exact order? do you also want all xhr calls to be in the right order? or why do you need console.log to be in that order? – Luke May 23 '18 at 16:49
  • Yes, I need index value of "site" variable in QueryKeyword() function becuase i need to perform some operation so is it possible to fetch "J" variable value(index of "site" variable) – Dhaval May 24 '18 at 05:37
0

You have to pass it in separately:

definition

function QueryKeyword(keyword, site, index, callback)
{
   ...
}

execution

QueryKeyword(searchTerm, site[j], j, function(reslt) {
   // I need to get j variable value here
   console.log(j);
});
dmgig
  • 4,400
  • 5
  • 36
  • 47
  • You don't "have to" do that though it's an option, but you're missing a vital step to make it work. –  May 22 '18 at 14:58
  • What's the step? And why tell him to use let? How do you know he's using ES6? – dmgig May 22 '18 at 14:59
  • I didn't tell him to use `let`. I only stated that using it would make it work. The missing step is passing the index into the callback when it gets invoked. –  May 22 '18 at 15:00
  • I got "J" value but not getting properly like 0,3 but i need a 0,1,2,3 like this sequence so i use async:false but it's not working with jsonp. If anyone have solution please help me. Thanks – Dhaval May 24 '18 at 16:15
  • @Dhaval I think you'd be better off with Luke's answer above. I did miss a key part here. – dmgig May 24 '18 at 16:32
  • @Dhaval that said, here is an Question about chaining ajax calls so they fire in order, one after another if that helps: https://stackoverflow.com/questions/16026942/how-do-i-chain-three-asynchronous-calls-using-jquery-promises – dmgig May 24 '18 at 16:35
  • Thanks for reply. But still no luck – Dhaval May 24 '18 at 16:41
  • I think Promises will work but i don't know how to implement in my above script. If anyone is know then please give the idea for the promises. – Dhaval May 24 '18 at 17:24
  • Check out this fiddle - you can maybe move your callback from 'success' to a chained 'then': https://jsfiddle.net/th2wayjh/1/ on your `$.ajax` call – dmgig May 24 '18 at 17:38
  • I tried the solution but no luck so please use the same function and loop which i mention in my question. Thanks – Dhaval May 25 '18 at 13:25
  • 1
    Foreach loop is working for me. Work likes a charm. Thanks – Dhaval May 27 '18 at 04:48