0

I'm using angular 1.5 with typescript, I can't access this property from the callback being returned from $http promise.

When I'm trying to access a private method from the callback 'this' is undefined

I have the following ServerAPI service:

export class ServerAPI implements IServerAPI {
    static $inject:Array<string> = ['$http', '$q'];

    constructor(private $http:ng.IHttpService,
                private $q:ng.IQService) {
    }

    postHandler(partialUrl:string, data?:any, config?:any):ng.IPromise<any> {
        let url = this.buildUrl(partialUrl);

        var result:ng.IPromise< any > = this.$http.post(url, data, config)
            .then((response:any):ng.IPromise<any> => this.handlerResponded(response, data))
            .catch((error:any):ng.IPromise<any> => this.handlerError(error, data));

        return result;
    }

    private handlerResponded(response:any, params:any):any {
        response.data.requestParams = params;
        return response.data;
    }

    private handlerError(error:any, params:any):any {
        error.requestParams = params;
        return error;
    }
}

Which been consumed by user.service:

export class UserService implements IUserService {
    static $inject:Array<string> = ['$q', 'serverAPI'];

    constructor(private $q:ng.IQService,
                private serverAPI:blocks.serverAPI.ServerAPI) {
        var vm = this;
        $rootScope.globals = $rootScope.globals || {};
        $rootScope.globals.currentUser = JSON.parse($window.localStorage.getItem('currentUser')) || null;

        this.getUserPermissions();
    }

    private getUserPermissions:() => IPromise<any> = () => {
        var promise = this.serverAPI.postHandler('MetaDataService/GetUserPermissions',
            {userID: this.getUser().profile.UserID})
            .then((res) => {
                this.updateUser('permissions', res.GetUserPermissionsResult); // NOT WORKING, this is undefined
            })
            .catch((response:any):ng.IPromise<any> => {
                this.updateUser('permissions', res.GetUserPermissionsResult); // NOT WORKING, this is undefined
            });
        return promise;
    };

    private updateUser:(property:string, value:any) => void = (property, value) => {
    };
}
Dor Cohen
  • 16,769
  • 23
  • 93
  • 161
  • Aren't typescript anonymous functions with _this inside the anonymous function? I'm not sure anymore. I think the more sure way might be to either save this as a local var, but normally typescript should do this transformation for you – Icepickle Feb 16 '16 at 16:22

1 Answers1

2

The issue is this line:

.then((response:any):ng.IPromise<any> => this.handlerResponded(response, data))

While your lexical scope is maintained in order to find the handlerResponded method the scope is not fully preserved in the output.

you can get around this in 2 ways:

  • inline your handler function rather than have it as a function on your class
  • you can bind the call to handlerResponded to the instance

example of binding:

.then((response:any):ng.IPromise<any> => this.handlerResponded(response, data).bind(this))
Brocco
  • 62,737
  • 12
  • 70
  • 76