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
2 Answers 2
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.
2 Comments
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.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
thiswithin$.ajax, declare as a different variable outside$.ajax