I want to send the same url param on all requests either it's get or post request, like this:
?region=us&toolName=abc
Is it possible by using AngularJS interceptor? Or is there other better way?
Thanks for your help.
Using an httpInterceptor would be best then you can check if other params already exist and extend them...or only use the ones shown
The AngularJS $http method lets you specify your HTTP request verb as well as such parameters via the config object which can contain a params object, which can be something like { region: "us", toolName: "abc" } which in turn becomes a query string. Example use:
$http({ url: "test.aspx", method: "GET", params: { region: "us", toolName: "abc" } }).then(
function(response){
alert("success!");
}, function(response){
alert("failure.");
}
Create a service to set default params request:
'use strict';
var ParamsService = function() {
return {
set: function (params) {
var defaultParams = {
region: 'us',
toolName: 'abc'
};
// Use any function to extend objects (currently, I'm using lodash)
return _.extend(defaultParams, params);
}
};
};
ParamsService.$inject = [
];
Request:
$http({
url: 'url.json',
method: 'GET',
params: ParamsService.set({otherProperty: otherValue})
})
.then(
function (data) {
},
function (error) {
}
);
It not good solution, but can help your case :)
$httpProvider.defaults.headers.common['key'] = 'value'
Related
with $http, we can do this:
var config = { headers: { 'something': 'anything' } };
$http.get('url/to/json', config)
.success(function() {
// do something…
})
i would like to do the same with a $resource reference (not working):
var config = { headers: { 'something': 'anything' } };
MyResource.get(
config,
function() { // success
// do something…
}
);
with the corresponding service declared like this :
.factory('MyResource', function($resource){
return $resource('url/to/json');
})
it's not working : the config object goes to the url and not in the http headers.
Is there a way to do that ?
headers for $resource is available since AngularJS 1.1.1. Make sure you have correct version used.
The format is
$resource('url/to/json', {}, {headers: { 'something': 'anything' }});
[edit by zuma]
The above doesn't seem right. The third parameter to $resource should be a different. This seems more correct to me:
$resource('url/to/json', {}, {
get: {
method: 'GET',
headers: { 'something': 'anything' }
}
});
The headers object inside a resource action supports both static values for its fields, but also dynamic values returned from a function.
$resource('url/to/json', {}, {
get: {
method: 'GET',
headers: {
'header_static': 'static_value',
'header_dynamic': dynamicHeaderVal
}
}
});
function dynamicHeaderVal(requestConfig){
// this function will be called every time the "get" action gets called
// the result will be used as value for the header item
// if it doesn't return a value, the key will not be present in the header
}
Demo Code
angular.module('Test',['ngResource'])
.controller('corsCtrl', function ($scope, $http, MyResource) {
$http.defaults.headers.common['test']= 'team'; //Using $http we can set header also
MyResource.get();
})
.factory('MyResource', function($resource) { //Services
return $resource('url/to/json');
})
JsFiddle DEMO
see in Request Header
To use "Content-Type" header you may need to specify a data body at least for versions around 1.4.7+ due to $http deleting headers without a data body that are === 'content-type'. See #10255 in 1.4.7/angular.js
I just set "data: false" to spoof it, without specifying a data body:
$resource('url/to/json', {}, {
get: {
method: 'GET',
data: false,
headers: { 'something': 'anything' }
}
});
You can set dynamic one-off headers by accessing the config API object in the resource
Demo Code
angular.
.factory('Resource',['$resource',function($resource){return $resource(baseUrl+'/resource/:id', {id: '#_id'}, {
update : {
method : 'POST',
url : baseUrl+'/resource/:id',
headers : {
'custom-header': function(config) {
// access variable via config.data
return config.data.customHeaderValue;
}
},
transformRequest: function(data) {
// you can delete the variable if you don't want it sent to the backend
delete data['customHeaderValue'];
// transform payload before sending
return JSON.stringify(data);
}
}
});
}]);
To execute
Resource.update({},{
customHeaderValue: setCustomHeaderValue
},
function (response) {
// do something ...
},function(error){
// process error
});
I am trying to build my first Angular $resource to give my application access to CRUD operations, but for some reason the actions being configured for the resource are not defined when I try to execute a query.
Here is my controller logic:
app.controller('MainCtrl', function ($scope, $http, $resource) {
var Alert = $resource('/WebApi/Alert/:type/:id',
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
$scope.systemUpdate = function (alert) {
var data = Alert.systemUpdate({ type: alert.Status, id: alert.AlertId }); // THIS LINE FAILS
console.log(data);
}
I get an error saying that Alert.systemUpdate is not defined. Am I doing something wrong here when configuring my $resource?
Change the definition of your Alert to
var Alert = $resource('/WebApi/Alert/:type/:id',
{},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
As mentionned in the documentation of $resource, the order of the parameters is the following:
1) Url
2) The default value of the parameters of the url, since you don't have any default value, you must provide an empty object
3) The actions (systemUpdate & autoArchive here)
Can anyone explain how can i make a post request with some values in the body of the request in Angularjs?
I tried this solution:
'getNomeServizio':
{ method: "POST",
url: basePath,
headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
}
In my controller:
(new Service()).$getNomeServizio(
$.param({chiave1: valore1, chiave2: valore2'})
).then(function (data) {
...
}, function (error) {
....
})
I want to use $resource but the request doesn't pass form-parameters.
Thanks in advance.
Try this:
Service.getNomeServizio({chiave1: 'valore1', chiave2: 'valore2'}, function(){
//success
}, function(){
//error
})
Resource:
angular.module('TicketService', ['ngResource'])
.factory('Ticket', ['$resource', function($resource){
var Ticket = $resource('/api/tickets/:id1/:action/:id2',
{
id1:'#id'
},
{
list: {
method: 'GET'
},
listByOwner: {
method: 'GET',
params: {
action:'owner',
id1:"#id"
}
}
update: {
method: 'PUT',
params:{}
}
});
return ticket;
}]);
Query:
$scope.userTickets = Ticket.listByOwner({
id : $rootScope.user.id
}, function(){
//success
}, function(response){});
Result:
Angularjs builds a wrong url, /api/tickets but it should be /api/tickets/2/owner. Any ideas why?
The # indicates that angular should look for the attribute on the data object, which is the second parameter (optional) in the Ticket service methods. In the first parameter you specify the request parameters. There are two ways you can fix this:
Add an empty object as the first parameter
$scope.userTickets = Ticket.listByOwner({},{
id : $rootScope.user.id
}, function(){
//success
}, function(response){});
Or rename the request parameter object key (from id to id1):
$scope.userTickets = Ticket.listByOwner({
id1 : $rootScope.user.id
}, function(){
//success
}, function(response){});
$resource is awesome providing very convenient way to handle web services.
What if GET and POST have to be performed on different URLs?
For example, GET URL is http://localhost/pleaseGethere/:id
and POST URL is http://localhost/pleasePosthere without any parameter
Use 'url' property of [actions] to override the default url.
$resource(url, [paramDefaults], [actions], options);
for example:
$resource('http://localhost/pleaseGethere/:id',{},{
getMethod:{
method:'GET',
isArray:true
}
postMethod:{
url:'http://localhost/pleasePosthere',
method:'POST',
isArray:false
}
}
Usage of Angular $resource: http://docs.angularjs.org/api/ngResource/service/$resource
You should be able to expose the URL as a parameter. I was able to do this:
$provide.factory('twitterResource', [
'$resource',
function($resource) {
return $resource(
'https://:url/:action',
{
url: 'search.twitter.com',
action: 'search.json',
q: '#ThingsYouSayToYourBestFriend',
callback: 'JSON_CALLBACK'
},
{
get: {
method: 'JSONP'
}
}
);
}
]);
Then you can overwrite the URL on your GET call.
The one caveat I found during my REALLY brief testing was that if I included http:// in the URL string, it didn't work. I didn't get an error message. It just did nothing.
If you add the hash with param names into the $resource call:
$resource('localhost/pleaseGethere/:id', {id: '#id'});
Then the :id will be mapped to id param when invoking the function (this will call GET localhost/pleaseGethere/123):
Resource.get({id: 123});
For POST, you simply don't assign the id param:
Resource.post({}, {name: "Joe"});
The proper URL will be called, which is in this case POST localhost/pleaseGethere (the trailing slash is stripped by ngResource).
See http://docs.angularjs.org/api/ngResource.$resource -> Examples -> Credit card resource for more details.
In addition to Iris Wong's answer, I wanted to give an example of having multiple params with multiple methods and actions:
angular
.module('thingApp')
.factory('ThingResource', ['$resource', '$state', returnThing]);
And the resource:
function returnThing($resource, $state) {
var mainUrl = '/api/stuffs/:stuffId/thing'
var params = {stuffId: '#_id', thingMongoId: '#_id', thingNumber: '#_id'}
return $resource(mainUrl, params, {
'save': {
url: '/api/stuffs/:stuffId/thing/:thingMongoId',
method: 'POST',
interceptor: {
responseError: function(e) {
console.warn('Problem making request to backend: ', e)
$state.go('oops')
}
}
},
'get': {
url: '/api/stuffs/:stuffId/thing/:thingMongoId',
method: 'GET',
interceptor: {
responseError: function(e) {
console.warn('Problem making request to backend: ', e)
$state.go('oops')
}
}
},
'assignThing':{
method: 'POST',
url: '/api/stuffs/:stuffId/thing/assign/:thingNumber'
}
});
}
Which gives 3 separate methods:
// POST to http://currnt_base_url/api/stuffs/:stuffId/thing/:thingMongoId
ThingResource.save({
stuffId:'56c3d1c47fe68be29e0f7652',
thingMongoId: '56c3d1c47fe6agwbe29e0f11111'})
// GET to current http://currnt_base_url/api/stuffs/:stuffId/thing/:thingMongoId
ThingResource.get({
stuffId:'56c3d1c47fe68be29e0f7652',
thingMongoId: '56c3d1c47fe6agwbe29e0f11111'})
// POST to http://currnt_base_url/api/stuffs/:stuffId/thing/assign/:thingNumber
ThingResource.assignThing({
stuffId:'56c3d1c47fe68be29e0f7652',
thingNumber: '999998'})
Follow this way:
(function () {
'use strict';
angular
.module("app")
.factory("SomeFactory", SomeFactory);
function SomeFactory($resource) {
var provider = "http://stackoverflow.com/:action/:id";
var params = {"id":"#id"};
var actions = {
"create": {"method": "POST", "params": {"action": "CreateAwesomePost"}},
"read": {"method": "POST", "params": {"action": "ReadSomethingInteresting"}},
"update": {"method": "POST", "params": {"action": "UpdateSomePost"}},
"delete": {"method": "GET", "params": {"action": "DeleteJustForFun"}}
};
return $resource(provider, params, actions);
}
})();
I hope it help! Enjoy!