Search code examples
angularjstypescriptangular-ui-routerrestangularinject

Angular inject $state service in config to redirect to a state in an interceptor


I am using restangular and I have an interceptor. The idea is that for every response 401 the interceptor should redirect to a different state.

The problem is that angular does not allow the injection of services in config. It only allows the injection of providers.

How can I have access to the $state: ng.ui.IStateService in my restangular interceptor?

I know I could inject the provider $stateProvider: ng.ui.IStateProvider but I don't think there is any way to navigate to certain state from the provider.

This is what I have:

/// <reference path="../../typings/globals/restangular/index.d.ts" />

((): void => {
    "use strict";

    angular
        .module("app")
        .config(configRestangular);

    configRestangular.$inject = [
        "$state",
        "RestangularProvider",
        "authSettings",
        "stateNames",
        "apiUrl"
    ];

    function isCustomValidationErrorResponse(response: restangular.IResponse) {
        return (response.data && response.data.customValidationError === true);
    }

    function configRestangular(
        $state: ng.ui.IStateService,
        restangularProvider: restangular.IProvider,
        authSettings: IAuthSettings,
        stateNames: IStateNames,
        apiUrl: string) {

        // restangular settings
        restangularProvider.setBaseUrl(apiUrl);

        restangularProvider.setErrorInterceptor((response: restangular.IResponse, deferred: ng.IDeferred<any>) => {
            if (response.status === 401) {
                $state.go(stateNames.login); //this will fail because $state cannot be injected here and I don't know how to navigate to a different state from $stateProvider
            } 
            return true;
        });
    }
})();

Solution

  • The way would be - configure Restangular.setErrorInterceptor in the .run() phase (check the Restangular not RestangularProvider). There we can get the $state as expected

    See also:

    Configuring in the run

    // Here I inject the service BaseUrlCalculator which I need
    app.run(function(Restangular, BaseUrlCalculator) {
        Restangular.setBaseUrl(BaseUrlCalculator.calculate());
    });