Extend angularjs $resource service to include common headers - angularjs

I want to write a wrapper service to the existing angular $resource service such that some custom headers are added to the http request by default. I am aware that we can set common headers using $httpProvider.defaults.headers.common. But this way all my requests would have this header and that is not what I want.
It would be lot more cleaner if the $resource service could be extended into a wrapper service in which I can define these common headers. This way I could selectively use this wrapper service wherever the common headers need to be added.

This may not be the answer you're looking for but I will share my thoughts. I'm using angular $http. The way I do it is I specify the correct header in every api call.
Something like this:
authenticatePlayer: function(postData) {
return $http({
method : 'POST',
url : api + 'auth/player',
data : postData,
headers : {'Content-Type' : 'application/json'}
});
},
uploadAvatar: function(email_address, fd) {
return $http({
method : 'POST',
url : api + 'player/' + email_address + '/avatar',
data : fd,
withCredentials: true,
headers : {'Content-Type' : undefined, 'X-Token' : credential.token},
transformRequest: angular.identity //awesome! automatically set to the correct header request
});
},
fbLogin: function(data) {
var xsrf = $.param({fb_access_token: data});
// console.log(postData);
return $http({
method : 'POST',
url : api + '/user/v1/login',
data : xsrf,
headers : {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'}
});
}
I'm not an expert in angular but this is the way I do it. Hope it helps :)

Related

How to POST content as application/x-www-form-urlencoded

angularjs $http.post is refusing to use my Content-Type
I am working with a contractor - their team are making server-side APIs while I'm putting together a javascript application using angularjs. They insist on making the api only allow calls with application/x-www-form-urlencoded calls, so I'm trying to figure out how to use $http to make a urlencoded call, and running into problems. All the instruction pages I'm finding seem focused on older versions of angularjs.
I try using the below code:
$scope.makeApiCall = function( ){
var apiData = {
"key1" : "value1",
"key2" : "value2"
};
var apiConfig = {
"headers" : {
"Content-Type" : "application/x-www-form-urlencoded;charset=utf-8;"
}
};
return $http.post('/Plugins/apiCall', apiData, apiConfig)
.then(function(response){
$scope.data=response.data;
});
};
But when I make the call, instead of using the Content-Type I provided, the developer tools report that it uses Content-Type: text/html; charset=utf-8
How do I get my $http.post to send the right Content-Type?
How to POST content as application/x-www-form-urlencoded
Use the $httpParamSerializerJQLike service to transform the data:
.controller(function($http, $httpParamSerializerJQLike) {
//...
$http({
url: myUrl,
method: 'POST',
data: $httpParamSerializerJQLike(myData),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
});
For more information, see
AngularJS $httpParamSerializerJQLike Service API Reference
Stackoverflow -- URL-encoding variables using only AngularJS services

$http header 'Content-Type' not appending in the header - AngularJS

I'm using $http to do a GET request and I wanted to append 'Content-Type': 'application/json' in the header. If I don't append this header 415 (Unsupported Media Type) error is thrown.
I'm using Apache 2.2.13 with ProxyPass, in which I DO NOT say
RequestHeader append Content-Type "application/json". However if I put the RequestHeader configuration in apache $http.get works fine and the 'Content-Type' is also appended.
Scenario 1 :
Using $http, trying GET request
Request :
$http({
method: 'GET',
headers: { 'Content-type': 'application/json'},
url: '/items/?customerId=5656'
});
Chrome Network Tab :
Scenario 2 :
Using Restangular, trying the same GET request
Request :
Restangular.setDefaultHeaders({'Content-Type': 'application/json'})
Restangular.setBaseUrl('/items')
Restangular.all('').getList({customerId: '103020'}, {'Content-Type': 'application/json'});
Chrome Network Tab :
The other interesting part here is, when I do some mistakes on the Request Header like,
Restangular.setDefaultHeaders({'Contentttt-Type': 'application/json'})
and try Scenario 1, I notice the following in the Chrome Network Tab.
Scenario 3 :
Using jQuery ajax, trying the same GET request
Request :
$.ajax({
url: "/items/?customerId=103020",
type: "GET",
beforeSend: function(xhr){xhr.setRequestHeader('Content-Type', 'application/json');},
success: function() { alert('Success!'); }
});
Chrome Network Tab :
Questions :
Is it necessary to add RequestHeader append Content-Type "application/json" in Apache configuration? But if I add that I get 415 errors on POST requests.
What is the problem with AngularJS and Restangular that it won't append Content-Type headers to its network calls on GET?
What is the best solution to solve this? I have tried out all the combinations but no luck!
Versions :
Angular : 1.2.22
Restangular : 1.4.0
On the one hand, with the $http service, you can override or add your headers using $httpProvider when calling the config method on your module :
module.config(function($http) {
$httpProvider.defaults.headers.get = { 'Content-Type : 'application/json' };
});
On the other hand, with the GET method, if your API is really RESTFull, only the Accept header should be set since you are not sending JSONdata.
Thus, use the above code for your PUT/POST methods and force the Accept header for the GETmethod:
module.config(function($http) {
$httpProvider.defaults.headers.post = { 'Content-Type : 'application/json'};
$httpProvider.defaults.headers.put = { 'Content-Type : 'application/json'};
$httpProvider.defaults.headers.get = { 'Accept : 'application/json'};
});
EDIT 1:
If you want to force the content-type in a GET request, you have to add a blank data :
$http({
method: 'GET',
data:'',
dataType:'json',
headers: { 'Content-type': 'application/json'},
url: '/items/?customerId=5656'
});
Setting a Content-Type header field on an HTTP request that doesn't have a request body (such as GET) is non-sense.
Maybe what you really want is set "Accept"?

How to have ajax call and use of RestFul webservice in angular js?

Well i have studied the angular js document and this code works perfect on the same server; somehow not working on cross site; localhost is reachable
module='user';
siteurl='http://localhost/angularjs';
url=siteurl+"/admin/"+module+"/list";
BlockUi();
$http({
url : url,
method : "post",
data : "",
headers : {'Content-Type':undefined}
}).then(function(responseText){
$scope.totaltablerows=responseText.data.response_data;
$scope.tablerows=$scope.totaltablerows;
UnblockUi();
$scope.searchFunction();
},function(error){
alert(JSON.stringify(error));
UnblockUi();
UnknownError();
});
What should i do so that this could work.
If your localhost is where your backend is also running, there is no need to explicitly mention that, so you code would look like:
BlockUi();
$http({
url : "/admin/user/list",
method : "post",
data : "",
headers : {'Content-Type': 'application/json'}
}).then(function(responseText){
$scope.totaltablerows=responseText.data.response_data;
$scope.tablerows=$scope.totaltablerows;
UnblockUi();
$scope.searchFunction();
},function(error){
alert(JSON.stringify(error));
UnblockUi();
UnknownError();
});
You do not need to mention the 'http://localhost/angularjs' at the beginning of the URL, also, why are you setting the content-type to undefined

send request without adding header in angular js

i'm trying to sending request to third party service. for that i need to delete default header 'x-access-token'. For that did like below
$http({
url: 'http://ip-api.com/json',
method: 'GET',
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
delete headers['x-access-token'];
return headers;
}
}).then(function(res){
console.log(res);
},function(error){
console.log(error);
});
By following this link .
But i'm getting this error
TypeError: Cannot convert object to primitive value
at angular.js:10514
at sendReq (angular.js:10333)
at $get.serverRequest (angular.js:10045)
at processQueue (angular.js:14567)
at angular.js:14583
at Scope.$get.Scope.$eval (angular.js:15846)
at Scope.$get.Scope.$digest (angular.js:15657)
at Scope.$get.Scope.$apply (angular.js:15951)
at done (angular.js:10364)
at completeRequest (angular.js:10536)
"transformRequest" does not work the same way to remove headers for individual requests past angularjs 1.4 release .From the documentation its clear that we should be using "headers" instead
eg:
$http({method: 'GET',
url: "url",
headers: {
'header-name': undefined
}
}).success(function(data){console.log(data)});
The $http service config object allows you to override the http header send for a specific request. See config property headers.
To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis, Use the headers property, setting the desired header to undefined.
NOTE: Set the desire header/headers to undefined like this, then it will not affect the global settings.
See example:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});
See more documentation.
This can take a list of headers or a function that return a list of headers. So for the non auth header request make a copy of the default headers remove the header you don't require and then make the request.
Hope this help well.

Set defaults header on AngularJS but don't use it on one specific request

For sending OAuth2 token I am setting up defaults header on AngularJS like this:
$http.defaults.headers.common['Authorization'] = 'Bearer ' + access_token;
This works great but I don't need this header (I get an error) for one specific request.
Is there a way of excluding defaults header when performing that request?
Thanks!
SOLVED
Thanks to Riron for getting me on a right path. Here's the answer:
$http({
method: 'GET',
url: 'http://.../',
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
delete headers['Authorization'];
return headers;
}
});
When you make your call with $http, you can override defaults headers by providing them directly in your request config:
$http({method: 'GET', url: '/someUrl', headers: {'Authorization' : 'NewValue'} }).success();
Otherwise you could transform your request using the transformRequest parameter, still in your $http config. See doc :
transformRequest – {function(data,headersGetter)|Array.<function(data, headersGetter)>} – transform
function or an array of such functions. The transform function takes
the http request body and headers and returns its transformed
(typically serialized) version.
This way you could delete an header for a single request before it's being send:
$http({method: 'GET',
url: '/someUrl',
transformRequest: function(data,headersGetter){ //Headers change here }
}).success();
For latecomers, whilst the solution might have worked - you actually shouldn't need to use transformRequest for this.
The Angular docs for the $http service actually have this exact situation covered:
To explicitly remove a header automatically added via
$httpProvider.defaults.headers on a per request basis, Use the headers
property, setting the desired header to undefined.
For example:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: {
test: 'test'
}
}
$http(req).success(function(){...}).error(function(){...});
Angular 1.4.0 can no longer modify request headers using transformRequest:
If one needs to dynamically add / remove headers it should be done in
a header function, for example:
$http.get(url, {
headers: {
'X-MY_HEADER': function(config) {
return 'abcd'; //you've got access to a request config object to specify header value dynamically
}
}
})
While the $httpProvider can override $http the use of intereceptors are 1 way of handling this, I end up doing it this way
function getMyStuff(blah) {
var req = {
method: 'GET',
url: 'http://...',
headers: {
'Authorization': undefined
}
}
return $http(req)
.then(function(response) {
return response.data;
});
}

Resources