Don't set extra header parameter in angularjs XHR request without mannual update

I am trying to send an extra header in an XHR request (init with $ resource). The following is my config

var app = angular.module('app',['angularMoment']).
run(function ($rootScope,$location,$route, $timeout, $http) { 
    var token = localStorage.getItem("userToken");
    $http.defaults.headers.common.token = token;
}

      

I change the hash parameters (e.g. after the login process) to navigate the app. So when I send an XHR request after the login process (reload manhual man), it sends the token (request header) as NULL . But when I reload my page manually it works fine (I am sending the token as a header). Also I tried with $route.reload()

but it doesn't work.

Please suggest how I can get rid of this problem.

thank

EDIT:

After trying the following code:

app.factory('tokenInterceptorService', ['$q', '$location', function ($q, $location) {

var tokenInterceptor = {};

var request = function (config) {

    config.headers = config.headers || {};

    var token = localStorage.getItem("userToken");

    config.headers.token = token;

    return config;
}

// if response errors with 401 redirect to lgoin
var response = function (rejection) {
    if (rejection.status === 401) {
        $location.path('/');
    }
    return $q.reject(rejection);
}

tokenInterceptor.request = request;
tokenInterceptor.response = response;

return tokenInterceptor;
}]);

app.config(function ($httpProvider) {
$httpProvider.interceptors.push('tokenInterceptorService');
});

app.run(function ($rootScope, $location,$route, $timeout, $http) {

$rootScope.config = {};
$rootScope.config.app_url = $location.url();
$rootScope.config.app_path = $location.path();
$rootScope.layout = {};
$rootScope.layout.loading = false;


$rootScope.$on('$routeChangeStart', function () {
    //need to validate
    console.log($rootScope.isValidated + "app");

    //show loading 
    $timeout(function(){
      $rootScope.layout.loading = true;          
    });
});
$rootScope.$on('$routeChangeSuccess', function () {
    //hide loading 
    $timeout(function(){
      $rootScope.layout.loading = false;
    }, 200);
});
$rootScope.$on('$routeChangeError', function () {

    alert('Something went wrong. Please refresh.');
    $rootScope.layout.loading = false;

});
})

      

Stop passing views in the application using .run "and capture in $rootScope.$on('$routeChangeError',

and give an error Error: [$ rootScope: inprog] $ digest is already running .

Error: [$ rootScope: inprog] $ digest already in progress

+3


source to share


3 answers


Since, if I understand correctly, your user token is always taken from localstorage, you can set the clock on this local storage key in your launch function (Demo plunker to work with Localstorage in angular: http://plnkr.co/edit/7hP13JAjPybxkRuMZLZ0 ? p = preview )

angular.module('app',[]).run(['$rootScope', '$http', function($root, $http) {
    $root.$watch(function() {
          return localStorage.getItem('userToken');
    }, function(userToken) {
       $http.defaults.headers.common.token = userToken;
    });
});

      



This should solve your problems without any interceptors, etc.

However, I would recommend using an HTTP interceptor as localStorage calls are slow or set to default values ​​when you actually set the user token after login or logout (store it also in a scope variable and initialize it in the startup part as you do now).

+2


source


You need to set up an interceptor that modifies every request sent to the server. You can read more forms here, but essentially you need to set up a factory service in your application to add a token header like so:

app.factory('tokenInterceptorService', ['$q', '$location', 'localStorage', function ($q, $location, localStorage) {

    var tokenInterceptor = {};

    var request = function (config) {

        config.headers = config.headers || {};

        var token = localStorage.getItem("userToken");
        if (token) {
            config.headers.token = token;
        }

        return config;
    }

    // if response errors with 401 redirect to lgoin
    var response = function (rejection) {
        if (rejection.status === 401) {
            $location.path('/login');
        }
        return $q.reject(rejection);
    }

    tokenInterceptor.request = request;
    tokenInterceptor.response = response;

    return tokenInterceptor;
}]);

      



and then register it in the config step with

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('tokenInterceptorService');
});

      

+2


source


module.run

runs well before anything else in the application (but after module.config

). Will it be installed localStorage

by then? I think this happens later, which is why you see this value after reloading the page.

The interceptor could go. How do you set the value to localStorage

?

Fiddle

+2


source







All Articles