It seems trivial, but these little mistakes have a tendency to cause a lot of debugging time.
getUrls(): ng.IPromise<any> {
if (this.urls != null) {
var urls = this.urls;
return this.$q(function (resolve, reject) { resolve(urls); });
}
this.urls = {};
var urls: any = this.urls;
return this.$http.get("conf/urls.json").then(function (response: any) {
urls.productionUrl = response.data.productionUrl;
urls.testingUrl = response.data.testingUrl;
return response.data;
});
}
Can you spot the problem? The problem occurs when two threads access the same method at the same time.if (this.urls != null) {
var urls = this.urls;
return this.$q(function (resolve, reject) { resolve(urls); });
}
this.urls = {};
var urls: any = this.urls;
return this.$http.get("conf/urls.json").then(function (response: any) {
urls.productionUrl = response.data.productionUrl;
urls.testingUrl = response.data.testingUrl;
return response.data;
});
}
Click here for the answer.
// the problem is in the replacing of the "urls" object with an empty object.
// This causes the second thread to believe the "urls" object exists
// (in the first if statement), and can be returned.
// It returns an empty object, containing no URLs whatsoever. The code below is better.
getUrls(): ng.IPromise<any> {
if (this.urls != null) {
var urls = this.urls;
return this.$q(function (resolve, reject) { resolve(urls); });
}
var service = this;
return this.$http.get("conf/urls.json").then(function (response: any) {
var urls = {
productionUrl: response.data.productionUrl,
testingUrl: response.data.testingUrl
};
service.urls = urls;
return response.data;
});
}
// This causes the second thread to believe the "urls" object exists
// (in the first if statement), and can be returned.
// It returns an empty object, containing no URLs whatsoever. The code below is better.
getUrls(): ng.IPromise<any> {
if (this.urls != null) {
var urls = this.urls;
return this.$q(function (resolve, reject) { resolve(urls); });
}
var service = this;
return this.$http.get("conf/urls.json").then(function (response: any) {
var urls = {
productionUrl: response.data.productionUrl,
testingUrl: response.data.testingUrl
};
service.urls = urls;
return response.data;
});
}
I always have problems wrapping my mind around JavaScript promises.