I realize that the TypeScript compiler is attempting to stay true to plain old JavaScript, as TypeScript is indeed JavaScript. However, there is a disconnect between what Intellisense interprets as the “this” keyword and what it actually resolves to during runtime. For example, consider the following TypeScript ajax call:
getAgencies() {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies",
{
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
}
and its corresponding callback:
onGetAgenciesComplete(agencies) {
var self = this;
if (agencies == null)
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({ name: a.Name, fullName: a.FullName, shortName: a.ShortName, bbox: a.BBox, countryCode: a.CountryCode });
});
if (Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
self.initMapPage(position, self);
},
function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
}
else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
// end of initialization
}
}
Now, when I hover over line “var self = this” in onGetAgenciesComplete within the TypeScript source file, the Intellisense definition of variable “self” indicates it is of type HomePageViewModelBase, where HomePageViewModelBase is the class that contain the above methods.
The generated Javascript for aforementioned is as follows:
HomePageViewModelBase.prototype.getAgencies = function () {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies", {
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
};
HomePageViewModelBase.prototype.onGetAgenciesComplete = function (agencies) {
var self = this;
if(agencies == null) {
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
} else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({
name: a.Name,
fullName: a.FullName,
shortName: a.ShortName,
bbox: a.BBox,
countryCode: a.CountryCode
});
});
if(Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
self.initMapPage(position, self);
}, function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
} else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
}
};
which when executed variable “self” in HomePageViewModelBase.prototype.onGetAgenciesComplete is resolved to what looks like an AjaxContext and not an instance of HomePageViewModelBase. Is this expected behavior or should I report this as a bug?
Yes you should probably report it to them as a bug, because the
thiswithin an$.ajax()is meant to refer to the$.ajax()object itself.If you want to go around it so that it works, change your success function to:
Or if you want the
thisto stand for your class, simply use the context method of $.ajax