Shamoon
Shamoon

Reputation: 43491

Why won't $http set a default header?

$http.post('http://localhost:7001/v1/sessions', {
  data: {
    username: $scope.user.username,
    password: $scope.user.password,
    type: 'sessions'
  }
})
.then(function(response) {
  if(response.data.data.token) {
    $http.defaults.headers.common.Authorization = response.data.data.token;
    $state.go('app.dashboard');
  } else {
    $scope.authError = response;
  }
}, function(x) {
  $scope.authError = 'Server Error';
});

I can confirm that the if condition gets called and a response.data.data.token is present.

It goes to the app.dashboard state but is intercepted by my ui-router:

$stateProvider.state('app', {
  abstract: true,
  url: '/app',
  templateUrl: 'tpl/app.html',
  resolve: {
    current_user: ['$http', function($http) {
      return $http.get('http://localhost:7001/v1/users/4/entities');
    }]
  }
})

That call, however, does not have anything set in the header. I thought that $http.defaults would set a default value in the header. What am I doing incorrectly?

Upvotes: 0

Views: 994

Answers (2)

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

I would prefered you to one service to use sharable data.

Code

app.service(dataService, function(){
   this.data = {}
   this.getData = function(){
      return data;
   };

   this.setTokenData = function(token){
      data.token = token;
   }
});

Now your code would be while setting token you could use dataService

  if(response.data.data.token) {
    dataService.setTokenData(response.data.data.token);
    $http.defaults.headers.common.Authorization = dataService.data.token; //dataService.getData().token;
    $state.go('app.dashboard');
  } else {
    $scope.authError = response;
  }

Then from service resolve you could use

$stateProvider.state('app', {
  abstract: true,
  url: '/app',
  templateUrl: 'tpl/app.html',
  resolve: {
    current_user: ['$http', 'dataService', function($http, dataService) {
      $http.defaults.headers.common.Authorization = dataService.getData().token;
      return $http.get('http://localhost:7001/v1/users/4/entities');
    }]
  }
})

Upvotes: 1

mohamedrias
mohamedrias

Reputation: 18566

You must set the default headers in the config method and not in your service.

Example:

myApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
}]);

Only in config you can configure the httpProvider. If you try to do that inside your service, it won't affect the $httpProvider service at all.

EDIT:

You must make use Interceptors in this scenario.

For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses, it is desirable to be able to intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests.

Refer Angular Docs Interceptor section

Just some sample code:

app.service('APIInterceptor', function($rootScope, UserService) {
    var service = this;

    service.request = function(config) { 
       // check if the token is available. Once the token is available get it here from the UserService.
        var access_token = UserService.getToken() || "unauthorized";
        if (access_token) {
            config.headers.authorization = access_token;
        }
        return config;
    };

    service.responseError = function(response) {
        return response;
    };
})

In your config

$httpProvider.interceptors.push('APIInterceptor');

Upvotes: 1

Related Questions