Right now, the only way that I know for setting tokens in headers dynamically for an angularjs call is via $http like so:
return $http.get({
url: 'https://my.backend.com/api/jokes',
params: {
'jokeId': '5',
},
headers: {
'Authorization': 'Bearer '+ $scope.myOAuthToken
}
});
But I want to figure out how to pass this via $resource, here's some pseudo-code that doesn't work:
...
.factory('myFactory',
['$resource',
function($resource){
return {
jokes: $resource('https://my.backend.com/api/jokes', null, {
query: {
method: 'GET'
}
})
};
}
]
);
...
return myFactory.jokes.query({
'jokeId': '5',
'headers': {
'Authorization': 'Bearer '+ $scope.myOAuthToken
}
});
How can I pass headers on the fly to $resource for angularjs?
I don't think this can be done the way you are trying, as the config object is not available on action method. But the action config method has it. So what you can do is, rather than returning resource directly, create a function that takes a parameter the authorization token and then construct the resource and return.
return {
jokes: function (token) {
return $resource('https://my.backend.com/api/jokes', null, {
query: {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token
}
}
})
}
};
Then call the service function as:
myFactory.jokes($scope.myOAuthToken).query({'jokeId': '5'});
Related
I have made a HTTP post API call to a URL.
I am getting the response, but I am confused how to write a success function, as there are many ways for it.
Here's my API call. Please help me how would the success function would be like?
var req = {
method: 'POST',
url: viewProfileurl,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + $rootScope.token,
},
params: {
'action':'view'
}
}
$http(req);
Angular uses promise internally in $http implementation i.e. $q:
A service that helps you run functions asynchronously, and use their
return values (or exceptions) when they are done processing.
So, there are two options:
1st option
You can use the .success and .error callbacks:
var req = {
method: 'POST',
url: viewProfileurl,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + $rootScope.token,
},
params: {
'action': 'view'
}
}
$http(req).success(function() {
// do on response success
}).error(function() {
});
But this .success & .error are deprecated.
Official deprecation notice
http://www.codelord.net/2015/05/25/dont-use-$https-success/
So, go for the 2nd option.
2nd Option
Use .then function instead
var req = {
method: 'POST',
url: viewProfileurl,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + $rootScope.token,
},
params: {
'action': 'view'
}
}
$http(req).then(function() {
// do on response success
}, function() {
// do on response failure
});
You need to write a success callback to retrive the data returned by your API.
$http(req)
.then(function (response) {
var data = resposne.data;
...
}, function (error) {
var errorStatusCode = error.StatusCode;
var errorStatus = error.Status;
...
});
Basically $http returns a promise and you need to write a callback function.
Or you can do something like this:
$http(req).success(function(respData) { var data = respData; ... });
$http(req).error(function(err) { ... });
This is success and error syntax
$http.get("/api/my/name")
.success(function(name) {
console.log("Your name is: " + name);
})
.error(function(response, status) {
console.log("The request failed with response " + response + " and status code " + status);
};
Using then
$http.get("/api/my/name")
.then(function(response) {
console.log("Your name is: " + response.data);
}, function(result) {
console.log("The request failed: " + result);
};
$http returns a promise that has a then function that you can use.
$http(req).then(function (data) { ...; });
The definition of then:
then(successCallback, failCallback)
Im building a RESTFul app and using Angular for my view. I want to use resources since is the best approach to it, i follow the how-to's and made some tweaks by my own to include the header api token, the code end like this:
fcbMixApp.factory('Resources', ['$resource',
function ($resource) {
return {
seminary: function (apiToken) {
return $resource('api/seminaries/:seminary', {}, {
save: {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiToken
}
},
update: {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + apiToken
}
}
});
},
attendant: function (apiToken) {
return $resource('api/attendants/:attendant', {}, {
save: {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiToken
}
},
update: {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + apiToken
}
}
});
}
}
}]);
But when i call it on my controller like this:
var Seminary = Resources.seminary(User.getAuthData().access_token);
I dont expect that line to make any request to my api, but it does. My code follows:
Seminary.query(function (data) {
$scope.seminaries = data;
});
So i finally make two calls.
What im doing wrong, or what should i change.
Thanks in advance.
You should set a header with the token:
$http.defaults.headers.common["Authorization"] = 'Bearer' + apiToken;
And not in the resource itself. You should set this when the user is logged in the first time, then you will send it on all requests.
Also consider your resource looking something like this, and making a separate one for attendant:
fcbMixApp.factory('Resources', ['$resource', function ($resource) {
function setRequestData(data) {
var requestData = new Object();
requestData.seminary = data;
return angular.toJson(requestData);
}
return $resource('api/seminaries/:seminary', {}, {
save: {
method: 'POST',
headers: {"Content-Type": "application/json"},
transformRequest: setRequestData
},
update: {
method: 'PUT',
headers: {"Content-Type": "application/json"},
transformRequest: setRequestData
}
});
}]);
Here is the solution for adding your Resource Authorization headers.
AngularJS: How to send auth token with $resource requests?
everything lives in the title.
when producing a resource in angular :
myModule.factory('MyResource', ['$resource', function ($resource) {
return $resource('api/MyResource/:id');
}]);
and using in a controller :
MyResource.save({att: att, att2: att2});
the Service sends the data in a json artifact ahead to the server.
I need to send the data in a x-www-form-urlencoded shape.
Where ought I modify my code to resolve that ?
Should pass the headers parameters
myModule.factory('MyResource', ['$resource', function ($resource) {
return $resource('api/MyResource/:id', {}, {
save: {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
});
}]);
then serialize your data before sending them with $httpParamSerializer
myModule.controller('appController', function ($httpParamSerializer) {
MyResource.save($httpParamSerializer({att: att, att2: att2}));
}
Complete answer (since angular 1.4). You need to include de dependency $httpParamSerializer
var res = $resource(serverUrl + 'Token', { }, {
save: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
});
res.save({ }, $httpParamSerializer({ param1: 'sdsd', param2: 'sdsd' }), function (response) {
}, function (error) {
});
I finally found myself:
When defining a resource and the associated instruction, the "headers" parameter comes in hand.
myModule.factory('MyResource', ['$resource', function ($resource) {
return $resource('api/MyResource/:id', {}, {
save: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
});
}]);
I have a need to transform response from service on each get, save, update. I've created a resource and added a transformer that gets executed, but the structure of object being returned is not the same as when I don't use transformer. Here I am talking about the structure of the response, not the object I am transforming.
Here is my resource:
angular.module('app')
.factory('Insureds', ['$resource', 'config', function ($resource, config) {
function transform(response) {
var insured = response.data.insured;
return response;
}
var memberServicesHostName = config.memberServicesHostName;
return $resource(memberServicesHostName + '/insureds/:insuredId', null,
{
'get': {
method: 'GET', 'withCredentials': true, interceptor:
{
response: function (response) { return transform(response).data; }
}
},
'update': { method: 'PUT', 'withCredentials': true },
'save': { method: 'POST', 'withCredentials': true }
});
}]);
When I don't use transformer "insured" is on the first level when the promise gets resolved it resolves as an instance of insured object. But with transformer there is wrapper object, that contains insured and responseStatus properties. It probably has to do with what I am returning from the "reponse" in the interceptor. What should one return, original response, like I am doing, or response.data, or response.resource.insured? I am confused...
The default response interceptor is like this:
function defaultResponseInterceptor(response) {
return response.resource;
}
Therefore, if you would like to preserve the default behaviour, you have to return response.resource instead of response.data:
return $resource(memberServicesHostName + '/insureds/:insuredId', null, {
get: {
method: 'GET',
withCredentials: true,
interceptor: {
response: function (response) {
return transform(response).resource;
}
}
},
...
Hope this helps.
I am trying to do a POST request with ngResources in AngularJS, I want to send my parameters in url and I have changed headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, in $save method in ngResources. The request goes out with the correct content type, but the data goes as a JSON. Is there any standard way to overcome this problem?
The factory
.factory('Token', ['$resource', function ($resource) {
return $resource('http://myProject/token/ ', { }, {
save: {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
});
}])
The calling function
.service('tokenService', ['$http', 'Token',
function ($http, Token) {
this.getToken = function () {
var t = new Token()
t.name = 'myName';
t.password = '78457'
return t.$save();
};
}])