0

Please help, I couldn't figure this out.

function Tour(el) {
 var tour = this;
 this.el = el;
 this.fetchPhotos = function() { 
 $.ajax('/photos.html', {
 data: {location: tour.el.data('location')},
 context: tour,
 success: function(response) {
 this.el.find('.photos').html(response).fadeIn();
 },
 error: function() {
 this.el.find('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
 },
 timeout: 3000,
 beforeSend: function() {
 this.el.addClass('is-fetching');
 },
 complete: function() {
 this.el.removeClass('is-fetching');
 }
 });
 }
 this.el.on('click', 'button', this.fetchPhotos);
}
$(document).ready(function() { 
 var paris = new Tour($('#paris'));
});

in the function above, I know the context: tour sets this inside the this.fetchPhotos function to reference Tour. So my question is why can this part of code tour.el.data('location') change to this.el.data('location')?

Thank you in advanced for your help

asked Nov 11, 2013 at 6:36
2
  • Read this . Commented Nov 11, 2013 at 6:38
  • you are losing context of this within $.ajax, declare as a different variable outside $.ajax Commented Nov 11, 2013 at 6:42

2 Answers 2

3

The reason that works is because tour.el.data('location') is called from fetchPhotos.

As long as you do

new Tour().fetchPhotos();

and not

var f = new Tour().fetchPhotos;
f();

the replacement will work.

But doing

this.el.on('click', 'button', this.fetchPhotos);

is like the latter. It does not work the same.

answered Nov 11, 2013 at 6:45
Sign up to request clarification or add additional context in comments.

2 Comments

To expand a little: a rule of thumb is, that the context is whatever is on the left side of the dot when the function is called. this.fetchPhotos doesn't call the method, instead one could imagine it to happen like this: var callback = arguments[2]; callback.call(that, args); where that === el.
@Derija93, good explanation for an often poorly explained concept.
0

As charlietfl wrote, this is a different context inside ajax callbacks, you have to cache this to any variable before ajax call and use that variable. Like you did in tour variable:

function Tour(el) {
 var tour = this;
 this.el = el;
 this.fetchPhotos = function() { 
 $.ajax('/photos.html', {
 data: {location: tour.el.data('location')},
 context: tour,
 success: function(response) {
 tour.el.find('.photos').html(response).fadeIn();
 },
 error: function() {
 tour.el.find('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
 },
 timeout: 3000,
 beforeSend: function() {
 tour.el.addClass('is-fetching');
 },
 complete: function() {
 tour.el.removeClass('is-fetching');
 }
 });
 }
 this.el.on('click', 'button', this.fetchPhotos);
}
$(document).ready(function() { 
 var paris = new Tour($('#paris'));
});

Outside of the ajax call (like the click event binder) it is ok to use this, but in those callback functions, it refers to that callback handler

answered Nov 11, 2013 at 7:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.