For a project I'm working on, I've uncovered a situation that doesn't make a whole lot of sense. I strongly suspect that, while I'm working in TypeScript, that my particular problem is due to a funny nuance of javascript, but I'm not sure how to prove it, or fix it.
Background
For the application I'm working on, I have a fairly basic service, that's responsible for communicating with a Web API.
The only thing that's different from what I normally do, is that instead of using TypeScript's 'lambda' syntax for a $http.get(...).then(...)
success callback, I'm using class functions instead, because A) the code I'm using is actually using the error callback, and B) the $http.get(...).then(success, error)
syntax is a bit messy to read with the lambda syntax.
// Not pretty, but sufficient.
this.$http.get(...).then(() => { ... });
// Ewwww...
this.$http.get(...)
.then(() => {
...
}, () => {
...
});
// Much better!
this.$http.get(...)
.then(onFooSuccess, onError);
Here's the relevant service:
namespace MyApp.Models {
export class WebApiResult<T> {
public data: T;
}
}
namespace MyApp.Services {
export class SomeService {
public status: SomeServiceStatus = new SomeServiceStatus();
public static $inject: string[] = ['$http'];
public constructor(
public $http: ng.IHttpService
) {
}
public doSomething(): ng.IPromise<SomeServiceStatus> {
this.$http.get('/api/some/SomeAction')
.then(this.onDoSomethingSuccess, this.describeError);
}
// This is the problem method. When this code runs,
// a type error is generated.
public onDoSomethingSuccess(result: Models.WebApiResult<SomeServiceStatus>): SomeServiceStatus | ng.IPromise<SomeServiceStatus> {
if(!result.data.isInSpecialState) {
return result.data;
}
// TypeError! Can't assign to undefined.
this.status = result.data;
return result.data;
}
public describeError(error: any) {
alert('oops');
}
}
export class SomeServiceStatus {
public isInSpecialState: boolean = false;
public someStatusMessage: string = '';
public someIdentifier: string = '';
}
angular
.module('app')
.service('someService', SomeService);
}
Problem
So, whenever you call this service, the $http
get is performed successfully. It's the success callback that's the problem, however - when the line this.status = result.data
is hit, it always throws an exception due to being unable to assign result.data
to property status
of undefined
.
At present, my theory is that this
does not actually refer to the SomeService
, but rather something else, possibly even the class method being used as the delegate.
Questions
This theory leads to some questions.
- What exactly is
this
referring to? Mousing over it in Visual Studio 2015 shows the 'helpful' text:this: this
. Thanks Microsoft. - Should
this
even be doing this? Is this a TypeScript bug, or is this merely me shooting myself in the foot with the generated JavaScript? - Are there any recommended stylistic choices when dealing with an AngularJS promise that has both a success and error callback? It might be that I'm not seeing a better way to write the code, or that I simply don't know something. It wouldn't be the first time that asking a SO question has taught me something.