Custom Headers for $resource - AngularJs - angularjs

Hi I am new to Angular JS, I am trying to put custom header in my $resource method, but I am not sure how would I do that
Following is my code :
function userFactory($resource, API) {
return $resource(API + '/users/:cmd', {}, {}, {
login: {method: 'GET', params: {cmd: 'current'}, headers: headerParam},
get: {method: 'GET'},
create: {method: 'POST'}
}
);
I would like to add a custom header 'headerParam' based on which user has logged in since the header would contain username and password specific details.

As I look at the header documentation in $http.config. This is map of string\ function, which implies you can call a function to set specific header
Something like
headers:{credentials: getUserCredentials}
And in the factory you can create the above method.
var getUserCredentials = function(config) {
}
I have not tried, see if it helps.

Related

add config in angular resource

I am using http-auth-interceptor for authentication. In http-auth-interceptor, I use the following way to login:
var data = 'username=' + encodeURIComponent(user.userId) + '&password=' + encodeURIComponent(user.password);
$http.post('api/authenticate', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ignoreAuthModule is used to tell ignoreAuthModule that this login method will be ignored by the auth interceptor.
Now, I have some request with $resource, like:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET'}
});
})
I want SomeDataService.get() is also ignored by the auth interceptors, because I need to control the 401 error by myself.
So, my question is, is there any way for ngResource that I can set config like that in $http.
[update based on comment]
I have listened the login-required event:
$rootScope.$on('event:auth-loginRequired', function (rejection) {
$log.log(rejection);
// I need to get the request url and for some specific url, need to do something.
$rootScope.loginPopup();
});
But the 'rejection' parameter has no context data of request I need. I need to get the request url and check, for some specified url, I need to do something.
After checking the document of ngResource, I got the solution as below:
.factory('SomeDataService', function ($resource) {
return $resource('api/some/data', {}, {
'get': { method: 'GET', ignoreAuthModule: 'ignoreAuthModule'}
});
})
Just add the config item as above. It will be equivalent ad:
$http.post('api/some/data', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
ignoreAuthModule: 'ignoreAuthModule'
})
ngResource module is build on top of $http.Hence it is not possible to configure all the stuffs you can do with $http in $resource.I think the below link will be guide you to have a clear understanding on $http and $resource

angularjs $resource JSONP doesn't work

I have created this ListFactory
factory('ListFactory', ['$resource', function ($resource) {
// var Chiamate = $resource('http://samedomain.com/file.json', {}, {
var Chiamate = $resource('http://anotherdomain.com/file.json', {}, {
query: {
// method: 'JSONP',
method: 'GET',
isArray: true,
cache : false,
}
});
return {
query: function(id) {
chiamate = Chiamate.query();
return chiamate;
}
};
}]);
in the controller i call the Factory using
$scope.results = ListFactory.query();
and into html i show the results
{{results}}
if i try to download a json file in same domain http://samedomain.com/file.json
using method: 'GET', => ok i see the resource
if i try to download a json file in another domain http://anotherdomain.com/file.json
using method: 'GET', => KO i see this error:
XMLHttpRequest cannot load http://anotherdomain.com/file.json No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://anotherdomain.com/file.json' is therefore not allowed access.
if i try to download a json file in another domain http://anotherdomain.com/file.json
using method: 'JSONP', => KO i don't see any error, but i don't see the result:
i use https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js
Any idea? Can you help me to get json file on another domain?
You will need the co-operation of the remote site for this to work. They need to send a Access-Control-Allow-Origin with your site name, otherwise the browser will throw the error you have seen.
See the following stackoverflow question, which has a more detailed answer
How does Access-Control-Allow-Origin header work?

How to retrieve objects from rest url with multiple parameters using angular

How can i create a factory that can retrieve data from
/rest/company/:companyid/employee/:id
when i use this url in the factory I get an error: Unknown provider companyidProvider
Thank you,
Kyle
Service:
app.factory('EmployeeByCompany', function ($resource,companyid) {
return $resource('app/rest/company/:companyid/employee/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': { method: 'GET'}
});
});
I'm guessing the error is from having the companyid as a parameter with $resource. What is the right way for a service to call this url?
If you are learning or geting started, try Restangular https://github.com/mgonto/restangular

Angularjs: Set a custom header on $resource before an action is called?

I have the following $resource definition:
angular.module("MyApp").factory("account", ["$resource",
function ($resource) {
var userResource = $resource("http://localhost/api/account/:id",
{
id: "#id"
},
{
register: {
method: "Post",
}
);
return userResource;
}]);
Before each call to user.query, get, register, etc... I need to set a custom header which is an authorization header with an access token.
Please note that setting the header globally would not work, because the access token might expire and be refreshed with a new one before every call to the $resource and therefore the authorization header will change. Also I need to set the header only on specific actions. For example I do not need it on the save action.
I read this article:
http://nils-blum-oeste.net/angularjs-send-auth-token-with-every-request/
which by the way is linked on several stackoverflow posts. But this is not what I need as it sets the token in the data of the action and I need it in the header.
for me, this was just a syntax problem - this post helped me out.
Dynamic Resource Headers
.factory("ResourceService", function() {
return {
Token: function(token){
return $resource("someurl/checktoken", {}, {
validateToken: {method:"POST", params: {}, headers: {"MY-AUTH-TOKEN": token}}
});
}}})

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