13

I'm having problems setting up a request interceptor in AngularJS using TypeScript

The following snippet works, not working variant is commented out. No matter what I inject in the constructor the local variables are undefined in the request method.

module Services
{
    export class AuthInterceptor
    {
        public static Factory(TokenService: Services.ITokenService)
        {
            return new AuthInterceptor(TokenService);
        }

        constructor(private TokenService: Services.ITokenService)
        {
            this.request = (config: ng.IRequestConfig) =>
            {
                config.headers = config.headers || {};
                if(this.TokenService.IsAuthorised())
                    config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
                return config;
            };
        }

        public request: (config: ng.IRequestConfig)=>ng.IRequestConfig;

/* THIS IS NOT WORKING

        public request(config)
        {
                    // this.TokenService is undefined here as well as $window or $q which I tried to inject
            config.headers = config.headers || {};
            if(this.TokenService.Token != "")
                config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
            return config;
        }
*/

    }
}

angular.module("Services")
    .config(($httpProvider: ng.IHttpProvider)=>
    {
        $httpProvider.interceptors.push(Services.AuthInterceptor.Factory);
    });

1 Answer 1

31

It is because of the wrong this. Solution:

    public request = (config) =>
    {
                // this.TokenService is undefined here as well as $window or $q which I tried to inject
        config.headers = config.headers || {};
        if(this.TokenService.Token != "")
            config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
        return config;
    }

To understand why you need this : https://www.youtube.com/watch?v=tvocUcbCupA&hd=1

Sign up to request clarification or add additional context in comments.

3 Comments

Brilliant! Thank you! So, angular breaks my this probably by storing the function in the local variable and then calling it? I got a feeling it's gonna be a loooong way from C# goodness for me :)
Well, after 4 hours of research and head scratching.. this has saved me. Thank you very much. I have now found _this explained well in the TS specification too, typescriptlang.org/Content/…
The explanation is easy. There is a different in invocation of the method. Most of people expect that when you define a service with interceptor methods, they will be invoked in a way myObj.request(<arguments...>). Unfortunately angular doesn't know that the method is a part of an object and it only takes a method and run without context. ie. var rMethod= myObj.request; rMethod(<arguments>). To fix it you need to define method as a lambdas to force proper object context. This is exactly what is explain in a YT link.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.