-2

I've the code something like below:

function foo(){
  $('div').each(function(){
   //here $(this) refers to selected div
  });
});

Now, when I call foo in setInterval the $(this) won't be referring to the div of each() method:

setInterval(function(){
  foo();
},5000);

I tried with bind():

setInterval(function(){
  foo();
}.bind(this),5000); //or bind(document.querySelectorAll('div'))

I'm incorrectly referring to the div $(this) really. What should I do?


Here's a proof that I'm getting undefined:

enter image description here

enter image description here

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231

1 Answers1

1

Assuming you want the code inside the each callback to have access to whatever value this has when the setInterval call is made, your code has two problems.

The first is that you're not binding foo itself. The code

setInterval(function(){
  foo();
}.bind(this),5000);

successfully binds this to the anonymous function function() { foo(); }. This anonymous function then makes a direct call to foo, which (in non-strict mode) sets the this for the call to the global object window or global, as happens with any direct function call.

You need to explicitly pass on the anonymous function's this to the foo call inside the anonymous function with call or apply:

setInterval(function(){
  foo.call(this);
}.bind(this),5000);

Now that foo has the right this, you need to make that this value accessible inside of the each callback. For that, you can consult How to access the correct `this` context inside a callback?, which will instruct you to store the outer this in another variable. You simply store this inside another variable and use that variable instead of this inside the inner callback:

function foo() {
  var outer_this_from_foo = this;

  $('.rsContent').each(function(){
    //here $(this) refers to selected div
    //but outer_this_from_foo refers to the `this` value just outside this callback

    var fI = $('>.img-responsive', outer_this_from_foo);
    // instead of $('>.img-responsive', this)

  });
};
Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • 1
    @C-linkNepal Edited; you can use `call`. To do it with `bind`, with `foo.bind(this)()` but that's needlessly resource-intensive (and not idiomatic); `foo.call(this)` will do the same thing. – apsillers Oct 16 '14 at 15:11
  • Sorry, but I'm still getting undefined. – Bhojendra Rauniyar Oct 16 '14 at 15:15
  • It's saying: Uncaught TypeError: Cannot read property 'call' of undefined – Bhojendra Rauniyar Oct 16 '14 at 15:19
  • 1
    Sounds like `foo` isn't defined in your anonymous function for some reason. Consider how your code differs from mine (which works fine) and you'll probably see wherever your code is going wrong: http://jsfiddle.net/x1s0ta42/ – apsillers Oct 16 '14 at 15:20
  • Is there anything mistake [here](http://jsfiddle.net/bj1zkx9n/3/) – Bhojendra Rauniyar Oct 16 '14 at 15:24
  • 1
    @C-linkNepal Yes, you're doing `foo().call(this)` instead of `foo.call(this)`. You're directly running `foo` and then trying to `call` the *result value* of `foo`, not `foo` itself. – apsillers Oct 16 '14 at 15:26
  • OH! but still getting undefined (i'm surprised) – Bhojendra Rauniyar Oct 16 '14 at 15:28
  • you may check edited question for a proof that I'm getting undefined... – Bhojendra Rauniyar Oct 16 '14 at 15:44
  • 1
    @C-linkNepal You haven't even used the information in my answer yet. You've skipped the entire second step of storing the `this` in another variable within `foo`; there is no `outer_this_from_foo = this` or similar in your code. – apsillers Oct 16 '14 at 15:49
  • please contribute giving a correct code of mine, I'm not understanding. – Bhojendra Rauniyar Oct 16 '14 at 15:53
  • could you please modify my code that would work (just in a fiddle), I'm still getting undefind. – Bhojendra Rauniyar Oct 16 '14 at 15:57
  • 1
    @C-linkNepal I've made another edit to the answer; if this is not clear enough, I do not understand how I can make it any more explicit; I'm sorry. Perhaps the explanation in the link I've provided will be clearer? – apsillers Oct 16 '14 at 16:01
  • I just tried that way too, but still getting undefined... – Bhojendra Rauniyar Oct 16 '14 at 16:07
  • And I'm getting undefined is not a function : [with this code](http://jsfiddle.net/bj1zkx9n/6/) – Bhojendra Rauniyar Oct 16 '14 at 16:12
  • In firefox : TypeError: n.createDocumentFragment is not a function – Bhojendra Rauniyar Oct 16 '14 at 16:15
  • 1
    Your `this` is `window`, which isn't a valid thing to `prepend` to, nor is it a valid context for a jQuery selection. Maybe I've misunderstood your question, because I don't understand what you expect `this` to be. Based on what I could understand from your question I thought you wanted bring the `this` from the code running `setInterval` into the `each` callback (as I said in my first sentence). Based on your code, however, that doesn't make any sense, because it seems you want to bring `window` into the `each` call, which breaks your code. – apsillers Oct 16 '14 at 16:37
  • 1
    That said, your stand-alone call to `foo()` before `setInterval` may also be breaking things. – apsillers Oct 16 '14 at 16:42